\n * Countly.q.push(['add_event',{\n * key:\"asyncButtonClick\",\n * segmentation: {\n * \"id\": ob.id\n * }\n * }]);\n */\n Countly.q = Countly.q || [];\n /**\n * Array of functions that are waiting to be notified that script has loaded and instantiated\n * @example\n * Countly.onload.push(function(){\n * console.log(\"script loaded\");\n * });\n */\n Countly.onload = Countly.onload || [];\n\n var SDK_VERSION = \"23.6.2\";\n var SDK_NAME = \"javascript_native_web\";\n\n // Using this on document.referrer would return an array with 15 elements in it. The 12th element (array[11]) would be the path we are looking for. Others would be things like password and such (use https://regex101.com/ to check more)\n var urlParseRE = /^(((([^:\\/#\\?]+:)?(?:(\\/\\/)((?:(([^:@\\/#\\?]+)(?:\\:([^:@\\/#\\?]+))?)@)?(([^:\\/#\\?\\]\\[]+|\\[[^\\/\\]@#?]+\\])(?:\\:([0-9]+))?))?)?)?((\\/?(?:[^\\/\\?#]+\\/+)*)([^\\?#]*)))?(\\?[^#]+)?)(#.*)?/;\n var apmLibrariesNotLoaded = true; // used to prevent loading apm scripts multiple times.\n\n /**\n * @this Countly\n * @param {Object} ob - Configuration object\n */\n var CountlyClass = function(ob) {\n var self = this;\n var global = !Countly.i;\n var sessionStarted = false;\n var apiPath = \"/i\";\n var readPath = \"/o/sdk\";\n var beatInterval = getConfig(\"interval\", ob, configurationDefaultValues.BEAT_INTERVAL);\n var queueSize = getConfig(\"queue_size\", ob, configurationDefaultValues.QUEUE_SIZE);\n var requestQueue = [];\n var eventQueue = [];\n var remoteConfigs = {};\n var crashLogs = [];\n var timedEvents = {};\n var ignoreReferrers = getConfig(\"ignore_referrers\", ob, []);\n var crashSegments = null;\n var autoExtend = true;\n var lastBeat;\n var storedDuration = 0;\n var lastView = null;\n var lastViewTime = 0;\n var lastViewStoredDuration = 0;\n var failTimeout = 0;\n var failTimeoutAmount = getConfig(\"fail_timeout\", ob, configurationDefaultValues.FAIL_TIMEOUT_AMOUNT);\n var inactivityTime = getConfig(\"inactivity_time\", ob, configurationDefaultValues.INACTIVITY_TIME);\n var inactivityCounter = 0;\n var sessionUpdate = getConfig(\"session_update\", ob, configurationDefaultValues.SESSION_UPDATE);\n var maxEventBatch = getConfig(\"max_events\", ob, configurationDefaultValues.MAX_EVENT_BATCH);\n var maxCrashLogs = getConfig(\"max_logs\", ob, null);\n var useSessionCookie = getConfig(\"use_session_cookie\", ob, true);\n var sessionCookieTimeout = getConfig(\"session_cookie_timeout\", ob, configurationDefaultValues.SESSION_COOKIE_TIMEOUT);\n var readyToProcess = true;\n var hasPulse = false;\n var offlineMode = getConfig(\"offline_mode\", ob, false);\n var lastParams = {};\n var trackTime = true;\n var startTime = getTimestamp();\n var lsSupport = true;\n var firstView = null;\n var deviceIdType = DeviceIdTypeInternalEnums.SDK_GENERATED;\n var isScrollRegistryOpen = false;\n var scrollRegistryTopPosition = 0;\n var trackingScrolls = false;\n var currentViewId = null; // this is the global variable for tracking the current view's ID. Used in view tracking. Becomes previous view ID at the end.\n var previousViewId = null; // this is the global variable for tracking the previous view's ID. Used in view tracking. First view has no previous view ID.\n var freshUTMTags = null;\n\n try {\n localStorage.setItem(\"cly_testLocal\", true);\n // clean up test\n localStorage.removeItem(\"cly_testLocal\");\n }\n catch (e) {\n log(logLevelEnums.ERROR, \"Local storage test failed, Halting local storage support: \" + e);\n lsSupport = false;\n }\n\n // create object to store consents\n var consents = {};\n for (var it = 0; it < Countly.features.length; it++) {\n consents[Countly.features[it]] = {};\n }\n\n this.initialize = function() {\n this.serialize = getConfig(\"serialize\", ob, Countly.serialize);\n this.deserialize = getConfig(\"deserialize\", ob, Countly.deserialize);\n this.getViewName = getConfig(\"getViewName\", ob, Countly.getViewName);\n this.getViewUrl = getConfig(\"getViewUrl\", ob, Countly.getViewUrl);\n this.getSearchQuery = getConfig(\"getSearchQuery\", ob, Countly.getSearchQuery);\n this.DeviceIdType = Countly.DeviceIdType; // it is Countly device Id type Enums for clients to use\n this.namespace = getConfig(\"namespace\", ob, \"\");\n this.clearStoredId = getConfig(\"clear_stored_id\", ob, false);\n this.app_key = getConfig(\"app_key\", ob, null);\n this.onload = getConfig(\"onload\", ob, []);\n this.utm = getConfig(\"utm\", ob, { source: true, medium: true, campaign: true, term: true, content: true });\n this.ignore_prefetch = getConfig(\"ignore_prefetch\", ob, true);\n this.rcAutoOptinAb = getConfig(\"rc_automatic_optin_for_ab\", ob, true);\n this.useExplicitRcApi = getConfig(\"use_explicit_rc_api\", ob, false);\n this.debug = getConfig(\"debug\", ob, false);\n this.test_mode = getConfig(\"test_mode\", ob, false);\n this.test_mode_eq = getConfig(\"test_mode_eq\", ob, false);\n this.metrics = getConfig(\"metrics\", ob, {});\n this.headers = getConfig(\"headers\", ob, {});\n this.url = stripTrailingSlash(getConfig(\"url\", ob, \"\"));\n this.app_version = getConfig(\"app_version\", ob, \"0.0\");\n this.country_code = getConfig(\"country_code\", ob, null);\n this.city = getConfig(\"city\", ob, null);\n this.ip_address = getConfig(\"ip_address\", ob, null);\n this.ignore_bots = getConfig(\"ignore_bots\", ob, true);\n this.force_post = getConfig(\"force_post\", ob, false);\n this.remote_config = getConfig(\"remote_config\", ob, false);\n this.ignore_visitor = getConfig(\"ignore_visitor\", ob, false);\n this.require_consent = getConfig(\"require_consent\", ob, false);\n this.track_domains = getConfig(\"track_domains\", ob, true);\n this.storage = getConfig(\"storage\", ob, \"default\");\n this.enableOrientationTracking = getConfig(\"enable_orientation_tracking\", ob, true);\n this.maxKeyLength = getConfig(\"max_key_length\", ob, configurationDefaultValues.MAX_KEY_LENGTH);\n this.maxValueSize = getConfig(\"max_value_size\", ob, configurationDefaultValues.MAX_VALUE_SIZE);\n this.maxSegmentationValues = getConfig(\"max_segmentation_values\", ob, configurationDefaultValues.MAX_SEGMENTATION_VALUES);\n this.maxBreadcrumbCount = getConfig(\"max_breadcrumb_count\", ob, null);\n this.maxStackTraceLinesPerThread = getConfig(\"max_stack_trace_lines_per_thread\", ob, configurationDefaultValues.MAX_STACKTRACE_LINES_PER_THREAD);\n this.maxStackTraceLineLength = getConfig(\"max_stack_trace_line_length\", ob, configurationDefaultValues.MAX_STACKTRACE_LINE_LENGTH);\n this.heatmapWhitelist = getConfig(\"heatmap_whitelist\", ob, []);\n self.hcErrorCount = getValueFromStorage(healthCheckCounterEnum.errorCount) || 0;\n self.hcWarningCount = getValueFromStorage(healthCheckCounterEnum.warningCount) || 0;\n self.hcStatusCode = getValueFromStorage(healthCheckCounterEnum.statusCode) || -1;\n self.hcErrorMessage = getValueFromStorage(healthCheckCounterEnum.errorMessage) || \"\";\n\n if (maxCrashLogs && !this.maxBreadcrumbCount) {\n this.maxBreadcrumbCount = maxCrashLogs;\n log(logLevelEnums.WARNING, \"initialize, 'maxCrashLogs' is deprecated. Use 'maxBreadcrumbCount' instead!\");\n }\n else if (!maxCrashLogs && !this.maxBreadcrumbCount) {\n this.maxBreadcrumbCount = 100;\n }\n\n if (this.storage === \"cookie\") {\n lsSupport = false;\n }\n\n if (!this.rcAutoOptinAb && !this.useExplicitRcApi) {\n log(logLevelEnums.WARNING, \"initialize, Auto opting is disabled, switching to explicit RC API\");\n this.useExplicitRcApi = true;\n }\n\n if (!Array.isArray(ignoreReferrers)) {\n ignoreReferrers = [];\n }\n\n if (this.url === \"\") {\n log(logLevelEnums.ERROR, \"initialize, Please provide server URL\");\n this.ignore_visitor = true;\n }\n if (getValueFromStorage(\"cly_ignore\")) {\n // opted out user\n this.ignore_visitor = true;\n }\n\n migrate();\n\n requestQueue = getValueFromStorage(\"cly_queue\") || [];\n eventQueue = getValueFromStorage(\"cly_event\") || [];\n remoteConfigs = getValueFromStorage(\"cly_remote_configs\") || {};\n\n if (this.clearStoredId) {\n // retrieve stored device ID and type from local storage and use it to flush existing events\n if (getValueFromStorage(\"cly_id\") && !tempIdModeWasEnabled) {\n this.device_id = getValueFromStorage(\"cly_id\");\n log(logLevelEnums.DEBUG, \"initialize, temporarily using the previous device ID to flush existing events\");\n deviceIdType = getValueFromStorage(\"cly_id_type\");\n if (!deviceIdType) {\n log(logLevelEnums.DEBUG, \"initialize, No device ID type info from the previous session, falling back to DEVELOPER_SUPPLIED, for event flushing\");\n deviceIdType = DeviceIdTypeInternalEnums.DEVELOPER_SUPPLIED;\n }\n sendEventsForced();\n // set them back to their initial values\n this.device_id = undefined;\n deviceIdType = DeviceIdTypeInternalEnums.SDK_GENERATED;\n }\n // then clear the storage so that a new device ID is set again later\n log(logLevelEnums.INFO, \"initialize, Clearing the device ID storage\");\n localStorage.removeItem(this.app_key + \"/cly_id\");\n localStorage.removeItem(this.app_key + \"/cly_id_type\");\n localStorage.removeItem(this.app_key + \"/cly_session\");\n }\n\n checkIgnore();\n\n if (window.name && window.name.indexOf(\"cly:\") === 0) {\n try {\n this.passed_data = JSON.parse(window.name.replace(\"cly:\", \"\"));\n }\n catch (ex) {\n log(logLevelEnums.ERROR, \"initialize, Could not parse name: \" + window.name + \", error: \" + ex);\n }\n }\n else if (location.hash && location.hash.indexOf(\"#cly:\") === 0) {\n try {\n this.passed_data = JSON.parse(location.hash.replace(\"#cly:\", \"\"));\n }\n catch (ex) {\n log(logLevelEnums.ERROR, \"initialize, Could not parse hash: \" + location.hash + \", error: \" + ex);\n }\n }\n\n if ((this.passed_data && this.passed_data.app_key && this.passed_data.app_key === this.app_key) || (this.passed_data && !this.passed_data.app_key && global)) {\n if (this.passed_data.token && this.passed_data.purpose) {\n if (this.passed_data.token !== getValueFromStorage(\"cly_old_token\")) {\n setToken(this.passed_data.token);\n setValueInStorage(\"cly_old_token\", this.passed_data.token);\n }\n var strippedList = [];\n // if whitelist is provided is an array\n if (Array.isArray(this.heatmapWhitelist)) {\n this.heatmapWhitelist.push(this.url);\n strippedList = this.heatmapWhitelist.map(function(e) {\n // remove trailing slashes from the entries\n return stripTrailingSlash(e);\n });\n }\n else {\n strippedList = [this.url];\n }\n // if the passed url is in the whitelist proceed\n if (strippedList.includes(this.passed_data.url)) {\n if (this.passed_data.purpose === \"heatmap\") {\n this.ignore_visitor = true;\n showLoader();\n loadJS(this.passed_data.url + \"/views/heatmap.js\", hideLoader);\n }\n }\n }\n }\n\n if (this.ignore_visitor) {\n log(logLevelEnums.WARNING, \"initialize, ignore_visitor:[\" + this.ignore_visitor + \"], this user will not be tracked\");\n return;\n }\n\n // init configuration is printed out here:\n // key values should be printed out as is\n log(logLevelEnums.DEBUG, \"initialize, app_key:[\" + this.app_key + \"], url:[\" + this.url + \"]\");\n log(logLevelEnums.DEBUG, \"initialize, device_id:[\" + getConfig(\"device_id\", ob, undefined) + \"]\");\n log(logLevelEnums.DEBUG, \"initialize, require_consent is enabled:[\" + this.require_consent + \"]\");\n try {\n log(logLevelEnums.DEBUG, \"initialize, metric override:[\" + JSON.stringify(this.metrics) + \"]\");\n log(logLevelEnums.DEBUG, \"initialize, header override:[\" + JSON.stringify(this.headers) + \"]\");\n // empty array is truthy and so would be printed if provided\n log(logLevelEnums.DEBUG, \"initialize, number of onload callbacks provided:[\" + this.onload.length + \"]\");\n // if the utm object is different to default utm object print it here\n log(logLevelEnums.DEBUG, \"initialize, utm tags:[\" + JSON.stringify(this.utm) + \"]\");\n // empty array printed if non provided\n if (ignoreReferrers) {\n log(logLevelEnums.DEBUG, \"initialize, referrers to ignore :[\" + JSON.stringify(ignoreReferrers) + \"]\");\n }\n }\n catch (e) {\n log(logLevelEnums.ERROR, \"initialize, Could not stringify some config object values\");\n }\n log(logLevelEnums.DEBUG, \"initialize, app_version:[\" + this.app_version + \"]\");\n\n // location info printed here\n log(logLevelEnums.DEBUG, \"initialize, provided location info; country_code:[\" + this.country_code + \"], city:[\" + this.city + \"], ip_address:[\" + this.ip_address + \"]\");\n\n // print non vital values only if provided by the developer or differs from the default value\n if (this.namespace !== \"\") {\n log(logLevelEnums.DEBUG, \"initialize, namespace given:[\" + this.namespace + \"]\");\n }\n if (this.clearStoredId) {\n log(logLevelEnums.DEBUG, \"initialize, clearStoredId flag set to:[\" + this.clearStoredId + \"]\");\n }\n if (this.ignore_prefetch) {\n log(logLevelEnums.DEBUG, \"initialize, ignoring pre-fetching and pre-rendering from counting as real website visits :[\" + this.ignore_prefetch + \"]\");\n }\n // if test mode is enabled warn the user\n if (this.test_mode) {\n log(logLevelEnums.WARNING, \"initialize, test_mode:[\" + this.test_mode + \"], request queue won't be processed\");\n }\n if (this.test_mode_eq) {\n log(logLevelEnums.WARNING, \"initialize, test_mode_eq:[\" + this.test_mode_eq + \"], event queue won't be processed\");\n }\n // if test mode is enabled warn the user\n if (this.heatmapWhitelist) {\n log(logLevelEnums.DEBUG, \"initialize, heatmap whitelist:[\" + JSON.stringify(this.heatmapWhitelist) + \"], these domains will be whitelisted\");\n }\n // if storage is se to something other than local storage\n if (this.storage !== \"default\") {\n log(logLevelEnums.DEBUG, \"initialize, storage is set to:[\" + this.storage + \"]\");\n }\n if (this.ignore_bots) {\n log(logLevelEnums.DEBUG, \"initialize, ignore traffic from bots :[\" + this.ignore_bots + \"]\");\n }\n if (this.force_post) {\n log(logLevelEnums.DEBUG, \"initialize, forced post method for all requests:[\" + this.force_post + \"]\");\n }\n if (this.remote_config) {\n log(logLevelEnums.DEBUG, \"initialize, remote_config callback provided:[\" + !!this.remote_config + \"]\");\n }\n if (typeof this.rcAutoOptinAb === \"boolean\") {\n log(logLevelEnums.DEBUG, \"initialize, automatic RC optin is enabled:[\" + this.rcAutoOptinAb + \"]\");\n }\n if (!this.useExplicitRcApi) {\n log(logLevelEnums.WARNING, \"initialize, will use legacy RC API. Consider enabling new API during init with use_explicit_rc_api flag\");\n }\n if (this.track_domains) {\n log(logLevelEnums.DEBUG, \"initialize, tracking domain info:[\" + this.track_domains + \"]\");\n }\n if (this.enableOrientationTracking) {\n log(logLevelEnums.DEBUG, \"initialize, enableOrientationTracking:[\" + this.enableOrientationTracking + \"]\");\n }\n if (!useSessionCookie) {\n log(logLevelEnums.WARNING, \"initialize, use_session_cookie is enabled:[\" + useSessionCookie + \"]\");\n }\n if (offlineMode) {\n log(logLevelEnums.DEBUG, \"initialize, offline_mode:[\" + offlineMode + \"], user info won't be send to the servers\");\n }\n if (offlineMode) {\n log(logLevelEnums.DEBUG, \"initialize, stored remote configs:[\" + JSON.stringify(remoteConfigs) + \"]\");\n }\n // functions, if provided, would be printed as true without revealing their content\n log(logLevelEnums.DEBUG, \"initialize, 'getViewName' callback override provided:[\" + (this.getViewName !== Countly.getViewName) + \"]\");\n log(logLevelEnums.DEBUG, \"initialize, 'getSearchQuery' callback override provided:[\" + (this.getSearchQuery !== Countly.getSearchQuery) + \"]\");\n\n // limits are printed here if they were modified \n if (this.maxKeyLength !== configurationDefaultValues.MAX_KEY_LENGTH) {\n log(logLevelEnums.DEBUG, \"initialize, maxKeyLength set to:[\" + this.maxKeyLength + \"] characters\");\n }\n if (this.maxValueSize !== configurationDefaultValues.MAX_VALUE_SIZE) {\n log(logLevelEnums.DEBUG, \"initialize, maxValueSize set to:[\" + this.maxValueSize + \"] characters\");\n }\n if (this.maxSegmentationValues !== configurationDefaultValues.MAX_SEGMENTATION_VALUES) {\n log(logLevelEnums.DEBUG, \"initialize, maxSegmentationValues set to:[\" + this.maxSegmentationValues + \"] key/value pairs\");\n }\n if (this.maxBreadcrumbCount !== configurationDefaultValues.MAX_BREADCRUMB_COUNT) {\n log(logLevelEnums.DEBUG, \"initialize, maxBreadcrumbCount for custom logs set to:[\" + this.maxBreadcrumbCount + \"] entries\");\n }\n if (this.maxStackTraceLinesPerThread !== configurationDefaultValues.MAX_STACKTRACE_LINES_PER_THREAD) {\n log(logLevelEnums.DEBUG, \"initialize, maxStackTraceLinesPerThread set to:[\" + this.maxStackTraceLinesPerThread + \"] lines\");\n }\n if (this.maxStackTraceLineLength !== configurationDefaultValues.MAX_STACKTRACE_LINE_LENGTH) {\n log(logLevelEnums.DEBUG, \"initialize, maxStackTraceLineLength set to:[\" + this.maxStackTraceLineLength + \"] characters\");\n }\n if (beatInterval !== configurationDefaultValues.BEAT_INTERVAL) {\n log(logLevelEnums.DEBUG, \"initialize, interval for heartbeats set to:[\" + beatInterval + \"] milliseconds\");\n }\n if (queueSize !== configurationDefaultValues.QUEUE_SIZE) {\n log(logLevelEnums.DEBUG, \"initialize, queue_size set to:[\" + queueSize + \"] items max\");\n }\n if (failTimeoutAmount !== configurationDefaultValues.FAIL_TIMEOUT_AMOUNT) {\n log(logLevelEnums.DEBUG, \"initialize, fail_timeout set to:[\" + failTimeoutAmount + \"] seconds of wait time after a failed connection to server\");\n }\n if (inactivityTime !== configurationDefaultValues.INACTIVITY_TIME) {\n log(logLevelEnums.DEBUG, \"initialize, inactivity_time set to:[\" + inactivityTime + \"] minutes to consider a user as inactive after no observable action\");\n }\n if (sessionUpdate !== configurationDefaultValues.SESSION_UPDATE) {\n log(logLevelEnums.DEBUG, \"initialize, session_update set to:[\" + sessionUpdate + \"] seconds to check if extending a session is needed while the user is active\");\n }\n if (maxEventBatch !== configurationDefaultValues.MAX_EVENT_BATCH) {\n log(logLevelEnums.DEBUG, \"initialize, max_events set to:[\" + maxEventBatch + \"] events to send in one batch\");\n }\n if (maxCrashLogs) {\n log(logLevelEnums.WARNING, \"initialize, max_logs set to:[\" + maxCrashLogs + \"] breadcrumbs to store for crash logs max, deprecated \");\n }\n if (sessionCookieTimeout !== configurationDefaultValues.SESSION_COOKIE_TIMEOUT) {\n log(logLevelEnums.DEBUG, \"initialize, session_cookie_timeout set to:[\" + sessionCookieTimeout + \"] minutes to expire a cookies session\");\n }\n\n log(logLevelEnums.INFO, \"initialize, Countly initialized\");\n\n var deviceIdParamValue = null;\n var searchQuery = self.getSearchQuery();\n var hasUTM = false;\n var utms = {};\n if (searchQuery) {\n var parts = searchQuery.substring(1).split(\"&\");\n for (var i = 0; i < parts.length; i++) {\n var nv = parts[i].split(\"=\");\n if (nv[0] === \"cly_id\") {\n setValueInStorage(\"cly_cmp_id\", nv[1]);\n }\n else if (nv[0] === \"cly_uid\") {\n setValueInStorage(\"cly_cmp_uid\", nv[1]);\n }\n else if (nv[0] === \"cly_device_id\") {\n deviceIdParamValue = nv[1];\n }\n else if ((nv[0] + \"\").indexOf(\"utm_\") === 0 && this.utm[nv[0].replace(\"utm_\", \"\")]) {\n utms[nv[0].replace(\"utm_\", \"\")] = nv[1];\n hasUTM = true;\n }\n }\n }\n\n // flag that indicates that the offline mode was enabled at the end of the previous app session \n var tempIdModeWasEnabled = (getValueFromStorage(\"cly_id\") === \"[CLY]_temp_id\");\n var developerSetDeviceId = getConfig(\"device_id\", ob, undefined);\n if (typeof developerSetDeviceId === \"number\") { // device ID should always be string\n developerSetDeviceId = developerSetDeviceId.toString();\n }\n\n // check if there wqs stored ID\n if (getValueFromStorage(\"cly_id\") && !tempIdModeWasEnabled) {\n this.device_id = getValueFromStorage(\"cly_id\");\n log(logLevelEnums.INFO, \"initialize, Set the stored device ID\");\n deviceIdType = getValueFromStorage(\"cly_id_type\");\n if (!deviceIdType) {\n log(logLevelEnums.INFO, \"initialize, No device ID type info from the previous session, falling back to DEVELOPER_SUPPLIED\");\n // there is a device ID saved but there is no device ID information saved \n deviceIdType = DeviceIdTypeInternalEnums.DEVELOPER_SUPPLIED;\n }\n }\n // if not check if device ID was provided with URL\n else if (deviceIdParamValue !== null) {\n log(logLevelEnums.INFO, \"initialize, Device ID set by URL\");\n this.device_id = deviceIdParamValue;\n deviceIdType = DeviceIdTypeInternalEnums.URL_PROVIDED;\n }\n // if not check if developer provided any ID\n else if (developerSetDeviceId) {\n log(logLevelEnums.INFO, \"initialize, Device ID set by developer\");\n this.device_id = developerSetDeviceId;\n if (ob && Object.keys(ob).length) {\n if (ob.device_id !== undefined) {\n deviceIdType = DeviceIdTypeInternalEnums.DEVELOPER_SUPPLIED;\n }\n }\n else if (Countly.device_id !== undefined) {\n deviceIdType = DeviceIdTypeInternalEnums.DEVELOPER_SUPPLIED;\n }\n }\n // if not check if offline mode is on\n else if (offlineMode || tempIdModeWasEnabled) {\n this.device_id = \"[CLY]_temp_id\";\n deviceIdType = DeviceIdTypeInternalEnums.TEMPORARY_ID;\n if (offlineMode && tempIdModeWasEnabled) {\n log(logLevelEnums.INFO, \"initialize, Temp ID set, continuing offline mode from previous app session\");\n }\n else if (offlineMode && !tempIdModeWasEnabled) {\n // this if we get here then it means either first init we enter offline mode or we cleared the device ID during the init and still user entered the offline mode\n log(logLevelEnums.INFO, \"initialize, Temp ID set, entering offline mode\");\n }\n else {\n // no device ID was provided, no offline mode flag was provided, in the previous app session we entered offline mode and now we carry on\n offlineMode = true;\n log(logLevelEnums.INFO, \"initialize, Temp ID set, enabling offline mode\");\n }\n }\n // if all fails generate an ID\n else {\n log(logLevelEnums.INFO, \"initialize, Generating the device ID\");\n this.device_id = getConfig(\"device_id\", ob, getStoredIdOrGenerateId());\n if (ob && Object.keys(ob).length) {\n if (ob.device_id !== undefined) {\n deviceIdType = DeviceIdTypeInternalEnums.DEVELOPER_SUPPLIED;\n }\n }\n else if (Countly.device_id !== undefined) {\n deviceIdType = DeviceIdTypeInternalEnums.DEVELOPER_SUPPLIED;\n }\n }\n\n // Store the device ID and device ID type\n setValueInStorage(\"cly_id\", this.device_id);\n setValueInStorage(\"cly_id_type\", deviceIdType);\n\n // as we have assigned the device ID now we can save the tags\n if (hasUTM) {\n freshUTMTags = {};\n for (var tag in this.utm) { // this.utm is a filter for allowed tags\n if (utms[tag]) { // utms is the tags that were passed in the URL\n this.userData.set(\"utm_\" + tag, utms[tag]);\n freshUTMTags[tag] = utms[tag];\n }\n else {\n this.userData.unset(\"utm_\" + tag);\n }\n }\n this.userData.save();\n }\n\n notifyLoaders();\n\n setTimeout(function() {\n heartBeat();\n if (self.remote_config) {\n self.fetch_remote_config(self.remote_config);\n }\n }, 1);\n document.documentElement.setAttribute(\"data-countly-useragent\", currentUserAgentString());\n // send instant health check request\n HealthCheck.sendInstantHCRequest();\n };\n\n /**\n * WARNING!!!\n * Should be used only for testing purposes!!!\n * \n * Resets Countly to its initial state (used mainly to wipe the queues in memory).\n * Calling this will result in a loss of data\n */\n this.halt = function() {\n log(logLevelEnums.WARNING, \"halt, Resetting Countly\");\n Countly.i = undefined;\n global = !Countly.i;\n sessionStarted = false;\n apiPath = \"/i\";\n readPath = \"/o/sdk\";\n beatInterval = 500;\n queueSize = 1000;\n requestQueue = [];\n eventQueue = [];\n remoteConfigs = {};\n crashLogs = [];\n timedEvents = {};\n ignoreReferrers = [];\n crashSegments = null;\n autoExtend = true;\n storedDuration = 0;\n lastView = null;\n lastViewTime = 0;\n lastViewStoredDuration = 0;\n failTimeout = 0;\n failTimeoutAmount = 60;\n inactivityTime = 20;\n inactivityCounter = 0;\n sessionUpdate = 60;\n maxEventBatch = 100;\n maxCrashLogs = null;\n useSessionCookie = true;\n sessionCookieTimeout = 30;\n readyToProcess = true;\n hasPulse = false;\n offlineMode = false;\n lastParams = {};\n trackTime = true;\n startTime = getTimestamp();\n lsSupport = true;\n firstView = null;\n deviceIdType = DeviceIdTypeInternalEnums.SDK_GENERATED;\n isScrollRegistryOpen = false;\n scrollRegistryTopPosition = 0;\n trackingScrolls = false;\n currentViewId = null;\n previousViewId = null;\n freshUTMTags = null;\n\n try {\n localStorage.setItem(\"cly_testLocal\", true);\n // clean up test\n localStorage.removeItem(\"cly_testLocal\");\n }\n catch (e) {\n log(logLevelEnums.ERROR, \"halt, Local storage test failed, will fallback to cookies\");\n lsSupport = false;\n }\n\n Countly.features = [featureEnums.SESSIONS, featureEnums.EVENTS, featureEnums.VIEWS, featureEnums.SCROLLS, featureEnums.CLICKS, featureEnums.FORMS, featureEnums.CRASHES, featureEnums.ATTRIBUTION, featureEnums.USERS, featureEnums.STAR_RATING, featureEnums.LOCATION, featureEnums.APM, featureEnums.FEEDBACK, featureEnums.REMOTE_CONFIG];\n\n // CONSENTS\n consents = {};\n for (var a = 0; a < Countly.features.length; a++) {\n consents[Countly.features[a]] = {};\n }\n\n self.app_key = undefined;\n self.device_id = undefined;\n self.onload = undefined;\n self.utm = undefined;\n self.ignore_prefetch = undefined;\n self.debug = undefined;\n self.test_mode = undefined;\n self.test_mode_eq = undefined;\n self.metrics = undefined;\n self.headers = undefined;\n self.url = undefined;\n self.app_version = undefined;\n self.country_code = undefined;\n self.city = undefined;\n self.ip_address = undefined;\n self.ignore_bots = undefined;\n self.force_post = undefined;\n self.rcAutoOptinAb = undefined;\n self.useExplicitRcApi = undefined;\n self.remote_config = undefined;\n self.ignore_visitor = undefined;\n self.require_consent = undefined;\n self.track_domains = undefined;\n self.storage = undefined;\n self.enableOrientationTracking = undefined;\n self.maxKeyLength = undefined;\n self.maxValueSize = undefined;\n self.maxSegmentationValues = undefined;\n self.maxBreadcrumbCount = undefined;\n self.maxStackTraceLinesPerThread = undefined;\n self.maxStackTraceLineLength = undefined;\n };\n\n /**\n * Modify feature groups for consent management. Allows you to group multiple features under one feature group\n * @param {object} features - object to define feature name as key and core features as value\n * @example
Adding all features under one group
\n * Countly.group_features({all:[\"sessions\",\"events\",\"views\",\"scrolls\",\"clicks\",\"forms\",\"crashes\",\"attribution\",\"users\"]});\n * //After this call Countly.add_consent(\"all\") to allow all features\n @example
Grouping features
\n * Countly.group_features({\n * activity:[\"sessions\",\"events\",\"views\"],\n * interaction:[\"scrolls\",\"clicks\",\"forms\"]\n * });\n * //After this call Countly.add_consent(\"activity\") to allow \"sessions\",\"events\",\"views\"\n * //or call Countly.add_consent(\"interaction\") to allow \"scrolls\",\"clicks\",\"forms\"\n * //or call Countly.add_consent(\"crashes\") to allow some separate feature\n */\n this.group_features = function(features) {\n log(logLevelEnums.INFO, \"group_features, Grouping features\");\n if (features) {\n for (var i in features) {\n if (!consents[i]) {\n if (typeof features[i] === \"string\") {\n consents[i] = { features: [features[i]] };\n }\n else if (features[i] && Array.isArray(features[i]) && features[i].length) {\n consents[i] = { features: features[i] };\n }\n else {\n log(logLevelEnums.ERROR, \"group_features, Incorrect feature list for [\" + i + \"] value: [\" + features[i] + \"]\");\n }\n }\n else {\n log(logLevelEnums.WARNING, \"group_features, Feature name [\" + i + \"] is already reserved\");\n }\n }\n }\n else {\n log(logLevelEnums.ERROR, \"group_features, Incorrect features:[\" + features + \"]\");\n }\n };\n\n /**\n * Check if consent is given for specific feature (either core feature of from custom feature group)\n * @param {string} feature - name of the feature, possible values, \"sessions\",\"events\",\"views\",\"scrolls\",\"clicks\",\"forms\",\"crashes\",\"attribution\",\"users\" or custom provided through {@link Countly.group_features}\n * @returns {Boolean} true if consent was given for the feature or false if it was not\n */\n this.check_consent = function(feature) {\n log(logLevelEnums.INFO, \"check_consent, Checking if consent is given for specific feature:[\" + feature + \"]\");\n if (!this.require_consent) {\n // we don't need to have specific consents\n log(logLevelEnums.INFO, \"check_consent, require_consent is off, no consent is necessary\");\n return true;\n }\n if (consents[feature]) {\n return !!(consents[feature] && consents[feature].optin);\n }\n log(logLevelEnums.ERROR, \"check_consent, No feature available for [\" + feature + \"]\");\n return false;\n };\n\n /**\n * Check and return the current device id type\n * @returns {number} a number that indicates the device id type\n */\n this.get_device_id_type = function() {\n log(logLevelEnums.INFO, \"check_device_id_type, Retrieving the current device id type.[\" + deviceIdType + \"]\");\n var type;\n switch (deviceIdType) {\n case DeviceIdTypeInternalEnums.SDK_GENERATED:\n type = self.DeviceIdType.SDK_GENERATED;\n break;\n case DeviceIdTypeInternalEnums.URL_PROVIDED:\n case DeviceIdTypeInternalEnums.DEVELOPER_SUPPLIED:\n type = self.DeviceIdType.DEVELOPER_SUPPLIED;\n break;\n case DeviceIdTypeInternalEnums.TEMPORARY_ID:\n type = self.DeviceIdType.TEMPORARY_ID;\n break;\n default:\n type = -1;\n break;\n }\n return type;\n };\n\n /**\n * Gets the current device id (of the CountlyClass instance)\n * @returns {string} device id\n */\n this.get_device_id = function() {\n log(logLevelEnums.INFO, \"get_device_id, Retrieving the device id: [\" + self.device_id + \"]\");\n return self.device_id;\n };\n\n /**\n * Check if any consent is given, for some cases, when crucial parts are like device_id are needed for any request\n * @returns {Boolean} true is has any consent given, false if no consents given\n */\n this.check_any_consent = function() {\n log(logLevelEnums.INFO, \"check_any_consent, Checking if any consent is given\");\n if (!this.require_consent) {\n // we don't need to have consents\n log(logLevelEnums.INFO, \"check_any_consent, require_consent is off, no consent is necessary\");\n return true;\n }\n for (var i in consents) {\n if (consents[i] && consents[i].optin) {\n return true;\n }\n }\n log(logLevelEnums.INFO, \"check_any_consent, No consents given\");\n return false;\n };\n\n /**\n * Add consent for specific feature, meaning, user allowed to track that data (either core feature of from custom feature group)\n * @param {string|array} feature - name of the feature, possible values, \"sessions\",\"events\",\"views\",\"scrolls\",\"clicks\",\"forms\",\"crashes\",\"attribution\",\"users\", etc or custom provided through {@link Countly.group_features}\n */\n this.add_consent = function(feature) {\n log(logLevelEnums.INFO, \"add_consent, Adding consent for [\" + feature + \"]\");\n if (Array.isArray(feature)) {\n for (var i = 0; i < feature.length; i++) {\n this.add_consent(feature[i]);\n }\n }\n else if (consents[feature]) {\n if (consents[feature].features) {\n consents[feature].optin = true;\n // this is added group, let's iterate through sub features\n this.add_consent(consents[feature].features);\n }\n else {\n // this is core feature\n if (consents[feature].optin !== true) {\n consents[feature].optin = true;\n updateConsent();\n setTimeout(function() {\n if (feature === featureEnums.SESSIONS && lastParams.begin_session) {\n self.begin_session.apply(self, lastParams.begin_session);\n lastParams.begin_session = null;\n }\n else if (feature === featureEnums.VIEWS && lastParams.track_pageview) {\n lastView = null;\n self.track_pageview.apply(self, lastParams.track_pageview);\n lastParams.track_pageview = null;\n }\n }, 1);\n }\n }\n }\n else {\n log(logLevelEnums.ERROR, \"add_consent, No feature available for [\" + feature + \"]\");\n }\n };\n\n /**\n * Remove consent for specific feature, meaning, user opted out to track that data (either core feature of from custom feature group)\n * @param {string|array} feature - name of the feature, possible values, \"sessions\",\"events\",\"views\",\"scrolls\",\"clicks\",\"forms\",\"crashes\",\"attribution\",\"users\", etc or custom provided through {@link Countly.group_features}\n * @param {Boolean} enforceConsentUpdate - regulates if a request will be sent to the server or not. If true, removing consents will send a request to the server and if false, consents will be removed without a request \n */\n this.remove_consent = function(feature) {\n log(logLevelEnums.INFO, \"remove_consent, Removing consent for [\" + feature + \"]\");\n this.remove_consent_internal(feature, true);\n };\n // removes consent without updating\n this.remove_consent_internal = function(feature, enforceConsentUpdate) {\n // if true updateConsent will execute when possible\n enforceConsentUpdate = enforceConsentUpdate || false;\n if (Array.isArray(feature)) {\n for (var i = 0; i < feature.length; i++) {\n this.remove_consent_internal(feature[i], enforceConsentUpdate);\n }\n }\n else if (consents[feature]) {\n if (consents[feature].features) {\n // this is added group, let's iterate through sub features\n this.remove_consent_internal(consents[feature].features, enforceConsentUpdate);\n }\n else {\n consents[feature].optin = false;\n // this is core feature\n if (enforceConsentUpdate && consents[feature].optin !== false) {\n updateConsent();\n }\n }\n }\n else {\n log(logLevelEnums.WARNING, \"remove_consent, No feature available for [\" + feature + \"]\");\n }\n };\n\n var consentTimer;\n var updateConsent = function() {\n if (consentTimer) {\n // delay syncing consents\n clearTimeout(consentTimer);\n consentTimer = null;\n }\n consentTimer = setTimeout(function() {\n var consentMessage = {};\n for (var i = 0; i < Countly.features.length; i++) {\n if (consents[Countly.features[i]].optin === true) {\n consentMessage[Countly.features[i]] = true;\n }\n else {\n consentMessage[Countly.features[i]] = false;\n }\n }\n toRequestQueue({ consent: JSON.stringify(consentMessage) });\n log(logLevelEnums.DEBUG, \"Consent update request has been sent to the queue.\");\n }, 1000);\n };\n\n this.enable_offline_mode = function() {\n log(logLevelEnums.INFO, \"enable_offline_mode, Enabling offline mode\");\n // clear consents\n this.remove_consent_internal(Countly.features, false);\n offlineMode = true;\n this.device_id = \"[CLY]_temp_id\";\n self.device_id = this.device_id;\n deviceIdType = DeviceIdTypeInternalEnums.TEMPORARY_ID;\n };\n\n this.disable_offline_mode = function(device_id) {\n if (!offlineMode) {\n log(logLevelEnums.WARNING, \"disable_offline_mode, Countly was not in offline mode.\");\n return;\n }\n log(logLevelEnums.INFO, \"disable_offline_mode, Disabling offline mode\");\n offlineMode = false;\n if (device_id && this.device_id !== device_id) {\n this.device_id = device_id;\n self.device_id = this.device_id;\n deviceIdType = DeviceIdTypeInternalEnums.DEVELOPER_SUPPLIED;\n setValueInStorage(\"cly_id\", this.device_id);\n setValueInStorage(\"cly_id_type\", DeviceIdTypeInternalEnums.DEVELOPER_SUPPLIED);\n log(logLevelEnums.INFO, \"disable_offline_mode, Changing id to: \" + this.device_id);\n }\n else {\n this.device_id = getStoredIdOrGenerateId();\n if (this.device_id === \"[CLY]_temp_id\") {\n this.device_id = generateUUID();\n }\n self.device_id = this.device_id;\n if (this.device_id !== getValueFromStorage(\"cly_id\")) {\n setValueInStorage(\"cly_id\", this.device_id);\n setValueInStorage(\"cly_id_type\", DeviceIdTypeInternalEnums.SDK_GENERATED);\n }\n }\n var needResync = false;\n if (requestQueue.length > 0) {\n for (var i = 0; i < requestQueue.length; i++) {\n if (requestQueue[i].device_id === \"[CLY]_temp_id\") {\n requestQueue[i].device_id = this.device_id;\n needResync = true;\n }\n }\n }\n if (needResync) {\n setValueInStorage(\"cly_queue\", requestQueue, true);\n }\n };\n\n /**\n * Start session\n * @param {boolean} noHeartBeat - true if you don't want to use internal heartbeat to manage session\n * @param {bool} force - force begin session request even if session cookie is enabled\n */\n this.begin_session = function(noHeartBeat, force) {\n log(logLevelEnums.INFO, \"begin_session, Starting the session. There was an ongoing session: [\" + sessionStarted + \"]\");\n if (noHeartBeat) {\n log(logLevelEnums.INFO, \"begin_session, Heartbeats are disabled\");\n }\n if (force) {\n log(logLevelEnums.INFO, \"begin_session, Session starts irrespective of session cookie\");\n }\n if (this.check_consent(featureEnums.SESSIONS)) {\n if (!sessionStarted) {\n if (this.enableOrientationTracking) {\n // report orientation\n this.report_orientation();\n add_event_listener(window, \"resize\", function() {\n self.report_orientation();\n });\n }\n lastBeat = getTimestamp();\n sessionStarted = true;\n autoExtend = !(noHeartBeat);\n var expire = getValueFromStorage(\"cly_session\");\n log(logLevelEnums.VERBOSE, \"begin_session, Session state, forced: [\" + force + \"], useSessionCookie: [\" + useSessionCookie + \"], seconds to expire: [\" + (expire - lastBeat) + \"], expired: [\" + (parseInt(expire) <= getTimestamp()) + \"] \");\n if (force || !useSessionCookie || !expire || parseInt(expire) <= getTimestamp()) {\n log(logLevelEnums.INFO, \"begin_session, Session started\");\n if (firstView === null) {\n firstView = true;\n }\n var req = {};\n req.begin_session = 1;\n req.metrics = JSON.stringify(getMetrics());\n toRequestQueue(req);\n }\n setValueInStorage(\"cly_session\", getTimestamp() + (sessionCookieTimeout * 60));\n }\n }\n else {\n lastParams.begin_session = arguments;\n }\n };\n\n /**\n * Report session duration\n * @param {int} sec - amount of seconds to report for current session\n */\n this.session_duration = function(sec) {\n log(logLevelEnums.INFO, \"session_duration, Reporting session duration\");\n if (this.check_consent(featureEnums.SESSIONS)) {\n if (sessionStarted) {\n log(logLevelEnums.INFO, \"session_duration, Session extended: \", sec);\n toRequestQueue({ session_duration: sec });\n extendSession();\n }\n }\n };\n\n /**\n * End current session\n * @param {int} sec - amount of seconds to report for current session, before ending it\n * @param {bool} force - force end session request even if session cookie is enabled\n */\n this.end_session = function(sec, force) {\n log(logLevelEnums.INFO, \"end_session, Ending the current session. There was an on going session:[\" + sessionStarted + \"]\");\n if (this.check_consent(featureEnums.SESSIONS)) {\n if (sessionStarted) {\n sec = sec || getTimestamp() - lastBeat;\n reportViewDuration();\n if (!useSessionCookie || force) {\n log(logLevelEnums.INFO, \"end_session, Session ended\");\n toRequestQueue({ end_session: 1, session_duration: sec });\n }\n else {\n this.session_duration(sec);\n }\n sessionStarted = false;\n }\n }\n };\n\n /**\n * Change current user/device id\n * @param {string} newId - new user/device ID to use. Must be a non-empty string value. Invalid values (like null, empty string or undefined) will be rejected\n * @param {boolean} merge - move data from old ID to new ID on server\n * */\n this.change_id = function(newId, merge) {\n log(logLevelEnums.INFO, \"change_id, Changing the ID\");\n if (merge) {\n log(logLevelEnums.INFO, \"change_id, Will merge the IDs\");\n }\n if (!newId || typeof newId !== \"string\" || newId.length === 0) {\n log(logLevelEnums.ERROR, \"change_id, The provided ID: [\" + newId + \"] is not a valid ID\");\n return;\n }\n if (offlineMode) {\n log(logLevelEnums.WARNING, \"change_id, Offline mode was on, initiating disabling sequence instead.\");\n this.disable_offline_mode(newId);\n return;\n }\n // eqeq is used here since we want to catch number to string checks too. type conversion might happen at a new init\n // eslint-disable-next-line eqeqeq\n if (this.device_id != newId) {\n if (!merge) {\n // empty event queue\n sendEventsForced();\n // end current session\n this.end_session(null, true);\n // clear timed events\n timedEvents = {};\n // clear all consents\n this.remove_consent_internal(Countly.features, false);\n }\n var oldId = this.device_id;\n this.device_id = newId;\n self.device_id = this.device_id;\n deviceIdType = DeviceIdTypeInternalEnums.DEVELOPER_SUPPLIED;\n setValueInStorage(\"cly_id\", this.device_id);\n setValueInStorage(\"cly_id_type\", DeviceIdTypeInternalEnums.DEVELOPER_SUPPLIED);\n log(logLevelEnums.INFO, \"change_id, Changing ID from:[\" + oldId + \"] to [\" + newId + \"]\");\n if (merge) {\n // no consent check here since 21.11.0\n toRequestQueue({ old_device_id: oldId });\n }\n else {\n // start new session for new ID \n this.begin_session(!autoExtend, true);\n }\n // if init time remote config was enabled with a callback function, remove currently stored remote configs and fetch remote config again\n if (this.remote_config) {\n remoteConfigs = {};\n setValueInStorage(\"cly_remote_configs\", remoteConfigs);\n this.fetch_remote_config(this.remote_config);\n }\n }\n };\n\n /**\n * Report custom event\n * @param {Object} event - Countly {@link Event} object\n * @param {string} event.key - name or id of the event\n * @param {number} [event.count=1] - how many times did event occur\n * @param {number=} event.sum - sum to report with event (if any)\n * @param {number=} event.dur - duration to report with event (if any)\n * @param {Object=} event.segmentation - object with segments key /values\n * */\n this.add_event = function(event) {\n log(logLevelEnums.INFO, \"add_event, Adding event: \", event);\n // initially no consent is given\n var respectiveConsent = false;\n switch (event.key) {\n case internalEventKeyEnums.NPS:\n respectiveConsent = this.check_consent(featureEnums.FEEDBACK);\n break;\n case internalEventKeyEnums.SURVEY:\n respectiveConsent = this.check_consent(featureEnums.FEEDBACK);\n break;\n case internalEventKeyEnums.STAR_RATING:\n respectiveConsent = this.check_consent(featureEnums.STAR_RATING);\n break;\n case internalEventKeyEnums.VIEW:\n respectiveConsent = this.check_consent(featureEnums.VIEWS);\n break;\n case internalEventKeyEnums.ORIENTATION:\n respectiveConsent = this.check_consent(featureEnums.USERS);\n break;\n case internalEventKeyEnums.ACTION:\n respectiveConsent = this.check_consent(featureEnums.CLICKS) || this.check_consent(featureEnums.SCROLLS);\n break;\n default:\n respectiveConsent = this.check_consent(featureEnums.EVENTS);\n }\n // if consent is given adds event to the queue\n if (respectiveConsent) {\n add_cly_events(event);\n }\n };\n\n /**\n * Add events to event queue\n * @memberof Countly._internals\n * @param {Event} event - countly event\n * @param {String} eventIdOverride - countly event ID\n */\n function add_cly_events(event, eventIdOverride) {\n // ignore bots\n if (self.ignore_visitor) {\n log(logLevelEnums.ERROR, \"Adding event failed. Possible bot or user opt out\");\n return;\n }\n\n if (!event.key) {\n log(logLevelEnums.ERROR, \"Adding event failed. Event must have a key property\");\n return;\n }\n\n if (!event.count) {\n event.count = 1;\n }\n // we omit the internal event keys from truncation. TODO: This is not perfect as it would omit a key that includes an internal event key and more too. But that possibility seems negligible. \n if (!internalEventKeyEnumsArray.includes(event.key)) {\n // truncate event name and segmentation to internal limits\n event.key = truncateSingleValue(event.key, self.maxKeyLength, \"add_cly_event\", log);\n }\n event.segmentation = truncateObject(event.segmentation, self.maxKeyLength, self.maxValueSize, self.maxSegmentationValues, \"add_cly_event\", log);\n var props = [\"key\", \"count\", \"sum\", \"dur\", \"segmentation\"];\n var e = createNewObjectFromProperties(event, props);\n e.timestamp = getMsTimestamp();\n var date = new Date();\n e.hour = date.getHours();\n e.dow = date.getDay();\n e.id = eventIdOverride || secureRandom();\n if (e.key === internalEventKeyEnums.VIEW) {\n e.pvid = previousViewId || \"\";\n }\n else {\n e.cvid = currentViewId || \"\";\n }\n eventQueue.push(e);\n setValueInStorage(\"cly_event\", eventQueue);\n log(logLevelEnums.INFO, \"With event ID: [\" + e.id + \"], successfully adding the last event:\", e);\n }\n\n /**\n * Start timed event, which will fill in duration property upon ending automatically\n * This works basically as a timer and does not create an event till end_event is called\n * @param {string} key - event name that will be used as key property\n * */\n this.start_event = function(key) {\n if (!key || typeof key !== \"string\") {\n log(logLevelEnums.WARNING, \"start_event, you have to provide a valid string key instead of: [\" + key + \"]\");\n return;\n }\n log(logLevelEnums.INFO, \"start_event, Starting timed event with key: [\" + key + \"]\");\n // truncate event name to internal limits\n key = truncateSingleValue(key, self.maxKeyLength, \"start_event\", log);\n if (timedEvents[key]) {\n log(logLevelEnums.WARNING, \"start_event, Timed event with key: [\" + key + \"] already started\");\n return;\n }\n timedEvents[key] = getTimestamp();\n };\n\n /**\n * Cancel timed event, cancels a timed event if it exists\n * @param {string} key - event name that will canceled\n * @returns {boolean} - returns true if the event was canceled and false if no event with that key was found\n * */\n this.cancel_event = function(key) {\n if (!key || typeof key !== \"string\") {\n log(logLevelEnums.WARNING, \"cancel_event, you have to provide a valid string key instead of: [\" + key + \"]\");\n return false;\n }\n log(logLevelEnums.INFO, \"cancel_event, Canceling timed event with key: [\" + key + \"]\");\n // truncate event name to internal limits. This is done incase start_event key was truncated.\n key = truncateSingleValue(key, self.maxKeyLength, \"cancel_event\", log);\n if (timedEvents[key]) {\n delete timedEvents[key];\n log(logLevelEnums.INFO, \"cancel_event, Timed event with key: [\" + key + \"] is canceled\");\n return true;\n }\n log(logLevelEnums.WARNING, \"cancel_event, Timed event with key: [\" + key + \"] was not found\");\n return false;\n };\n\n /**\n * End timed event\n * @param {string|object} event - event key if string or Countly event same as passed to {@link Countly.add_event}\n * */\n this.end_event = function(event) {\n if (!event) {\n log(logLevelEnums.WARNING, \"end_event, you have to provide a valid string key or event object instead of: [\" + event + \"]\");\n return;\n }\n log(logLevelEnums.INFO, \"end_event, Ending timed event\");\n if (typeof event === \"string\") {\n // truncate event name to internal limits. This is done incase start_event key was truncated.\n event = truncateSingleValue(event, self.maxKeyLength, \"end_event\", log);\n event = { key: event };\n }\n if (!event.key) {\n log(logLevelEnums.ERROR, \"end_event, Timed event must have a key property\");\n return;\n }\n if (!timedEvents[event.key]) {\n log(logLevelEnums.ERROR, \"end_event, Timed event with key: [\" + event.key + \"] was not started\");\n return;\n }\n event.dur = getTimestamp() - timedEvents[event.key];\n this.add_event(event);\n delete timedEvents[event.key];\n };\n\n /**\n * Report device orientation\n * @param {string=} orientation - orientation as landscape or portrait\n * */\n this.report_orientation = function(orientation) {\n log(logLevelEnums.INFO, \"report_orientation, Reporting orientation\");\n if (this.check_consent(featureEnums.USERS)) {\n add_cly_events({\n key: internalEventKeyEnums.ORIENTATION,\n segmentation: {\n mode: orientation || getOrientation(),\n },\n });\n }\n };\n\n /**\n * Report user conversion to the server (when user signup or made a purchase, or whatever your conversion is), if there is no campaign data, user will be reported as organic\n * @param {string=} campaign_id - id of campaign, or will use the one that is stored after campaign link click\n * @param {string=} campaign_user_id - id of user's click on campaign, or will use the one that is stored after campaign link click\n * \n * @deprecated use 'recordDirectAttribution' in place of this call\n * */\n this.report_conversion = function(campaign_id, campaign_user_id) {\n log(logLevelEnums.WARNING, \"report_conversion, Deprecated function call! Use 'recordDirectAttribution' in place of this call. Call will be redirected now!\");\n this.recordDirectAttribution(campaign_id, campaign_user_id);\n };\n /**\n * Report user conversion to the server (when user signup or made a purchase, or whatever your conversion is), if there is no campaign data, user will be reported as organic\n * @param {string=} campaign_id - id of campaign, or will use the one that is stored after campaign link click\n * @param {string=} campaign_user_id - id of user's click on campaign, or will use the one that is stored after campaign link click\n * */\n this.recordDirectAttribution = function(campaign_id, campaign_user_id) {\n log(logLevelEnums.INFO, \"recordDirectAttribution, Recording the attribution for campaign ID: [\" + campaign_id + \"] and the user ID: [\" + campaign_user_id + \"]\");\n if (this.check_consent(featureEnums.ATTRIBUTION)) {\n campaign_id = campaign_id || getValueFromStorage(\"cly_cmp_id\") || \"cly_organic\";\n campaign_user_id = campaign_user_id || getValueFromStorage(\"cly_cmp_uid\");\n\n if (campaign_user_id) {\n toRequestQueue({ campaign_id: campaign_id, campaign_user: campaign_user_id });\n }\n else {\n toRequestQueue({ campaign_id: campaign_id });\n }\n }\n };\n\n /**\n * Provide information about user\n * @param {Object} user - Countly {@link UserDetails} object\n * @param {string=} user.name - user's full name\n * @param {string=} user.username - user's username or nickname\n * @param {string=} user.email - user's email address\n * @param {string=} user.organization - user's organization or company\n * @param {string=} user.phone - user's phone number\n * @param {string=} user.picture - url to user's picture\n * @param {string=} user.gender - M value for male and F value for female\n * @param {number=} user.byear - user's birth year used to calculate current age\n * @param {Object=} user.custom - object with custom key value properties you want to save with user\n * */\n this.user_details = function(user) {\n log(logLevelEnums.INFO, \"user_details, Trying to add user details: \", user);\n if (this.check_consent(featureEnums.USERS)) {\n sendEventsForced(); // flush events to event queue to prevent a drill issue\n log(logLevelEnums.INFO, \"user_details, flushed the event queue\");\n // truncating user values and custom object key value pairs\n user.name = truncateSingleValue(user.name, self.maxValueSize, \"user_details\", log);\n user.username = truncateSingleValue(user.username, self.maxValueSize, \"user_details\", log);\n user.email = truncateSingleValue(user.email, self.maxValueSize, \"user_details\", log);\n user.organization = truncateSingleValue(user.organization, self.maxValueSize, \"user_details\", log);\n user.phone = truncateSingleValue(user.phone, self.maxValueSize, \"user_details\", log);\n user.picture = truncateSingleValue(user.picture, 4096, \"user_details\", log);\n user.gender = truncateSingleValue(user.gender, self.maxValueSize, \"user_details\", log);\n user.byear = truncateSingleValue(user.byear, self.maxValueSize, \"user_details\", log);\n user.custom = truncateObject(user.custom, self.maxKeyLength, self.maxValueSize, self.maxSegmentationValues, \"user_details\", log);\n var props = [\"name\", \"username\", \"email\", \"organization\", \"phone\", \"picture\", \"gender\", \"byear\", \"custom\"];\n toRequestQueue({ user_details: JSON.stringify(createNewObjectFromProperties(user, props)) });\n }\n };\n\n /** ************************\n * Modifying custom property values of user details\n * Possible modification commands\n * - inc, to increment existing value by provided value\n * - mul, to multiply existing value by provided value\n * - max, to select maximum value between existing and provided value\n * - min, to select minimum value between existing and provided value\n * - setOnce, to set value only if it was not set before\n * - push, creates an array property, if property does not exist, and adds value to array\n * - pull, to remove value from array property\n * - addToSet, creates an array property, if property does not exist, and adds unique value to array, only if it does not yet exist in array\n ************************* */\n var customData = {};\n var change_custom_property = function(key, value, mod) {\n if (self.check_consent(featureEnums.USERS)) {\n if (!customData[key]) {\n customData[key] = {};\n }\n if (mod === \"$push\" || mod === \"$pull\" || mod === \"$addToSet\") {\n if (!customData[key][mod]) {\n customData[key][mod] = [];\n }\n customData[key][mod].push(value);\n }\n else {\n customData[key][mod] = value;\n }\n }\n };\n\n /**\n * Control user related custom properties. Don't forget to call save after finishing manipulation of custom data\n * @namespace Countly.userData\n * @name Countly.userData\n * @example\n * //set custom key value property\n * Countly.userData.set(\"twitter\", \"hulk@rowboat\");\n * //create or increase specific number property\n * Countly.userData.increment(\"login_count\");\n * //add new value to array property if it is not already there\n * Countly.userData.push_unique(\"selected_category\", \"IT\");\n * //send all custom property modified data to server\n * Countly.userData.save();\n */\n this.userData = {\n /**\n * Sets user's custom property value\n * @memberof Countly.userData\n * @param {string} key - name of the property to attach to user\n * @param {string|number} value - value to store under provided property\n * */\n set: function(key, value) {\n log(logLevelEnums.INFO, \"[userData] set, Setting user's custom property value: [\" + value + \"] under the key: [\" + key + \"]\");\n // truncate user's custom property value to internal limits\n key = truncateSingleValue(key, self.maxKeyLength, \"userData set\", log);\n value = truncateSingleValue(value, self.maxValueSize, \"userData set\", log);\n customData[key] = value;\n },\n /**\n * Unset/deletes user's custom property\n * @memberof Countly.userData\n * @param {string} key - name of the property to delete\n * */\n unset: function(key) {\n log(logLevelEnums.INFO, \"[userData] unset, Resetting user's custom property with key: [\" + key + \"] \");\n customData[key] = \"\";\n },\n /**\n * Sets user's custom property value only if it was not set before\n * @memberof Countly.userData\n * @param {string} key - name of the property to attach to user\n * @param {string|number} value - value to store under provided property\n * */\n set_once: function(key, value) {\n log(logLevelEnums.INFO, \"[userData] set_once, Setting user's unique custom property value: [\" + value + \"] under the key: [\" + key + \"] \");\n // truncate user's custom property value to internal limits\n key = truncateSingleValue(key, self.maxKeyLength, \"userData set_once\", log);\n value = truncateSingleValue(value, self.maxValueSize, \"userData set_once\", log);\n change_custom_property(key, value, \"$setOnce\");\n },\n /**\n * Increment value under the key of this user's custom properties by one\n * @memberof Countly.userData\n * @param {string} key - name of the property to attach to user\n * */\n increment: function(key) {\n log(logLevelEnums.INFO, \"[userData] increment, Increasing user's custom property value under the key: [\" + key + \"] by one\");\n // truncate property name wrt internal limits\n key = truncateSingleValue(key, self.maxKeyLength, \"userData increment\", log);\n change_custom_property(key, 1, \"$inc\");\n },\n /**\n * Increment value under the key of this user's custom properties by provided value\n * @memberof Countly.userData\n * @param {string} key - name of the property to attach to user\n * @param {number} value - value by which to increment server value\n * */\n increment_by: function(key, value) {\n log(logLevelEnums.INFO, \"[userData] increment_by, Increasing user's custom property value under the key: [\" + key + \"] by: [\" + value + \"]\");\n // truncate property name and value wrt internal limits \n key = truncateSingleValue(key, self.maxKeyLength, \"userData increment_by\", log);\n value = truncateSingleValue(value, self.maxValueSize, \"userData increment_by\", log);\n change_custom_property(key, value, \"$inc\");\n },\n /**\n * Multiply value under the key of this user's custom properties by provided value\n * @memberof Countly.userData\n * @param {string} key - name of the property to attach to user\n * @param {number} value - value by which to multiply server value\n * */\n multiply: function(key, value) {\n log(logLevelEnums.INFO, \"[userData] multiply, Multiplying user's custom property value under the key: [\" + key + \"] by: [\" + value + \"]\");\n // truncate key value pair wrt internal limits\n key = truncateSingleValue(key, self.maxKeyLength, \"userData multiply\", log);\n value = truncateSingleValue(value, self.maxValueSize, \"userData multiply\", log);\n change_custom_property(key, value, \"$mul\");\n },\n /**\n * Save maximal value under the key of this user's custom properties\n * @memberof Countly.userData\n * @param {string} key - name of the property to attach to user\n * @param {number} value - value which to compare to server's value and store maximal value of both provided\n * */\n max: function(key, value) {\n log(logLevelEnums.INFO, \"[userData] max, Saving user's maximum custom property value compared to the value: [\" + value + \"] under the key: [\" + key + \"]\");\n // truncate key value pair wrt internal limits\n key = truncateSingleValue(key, self.maxKeyLength, \"userData max\", log);\n value = truncateSingleValue(value, self.maxValueSize, \"userData max\", log);\n change_custom_property(key, value, \"$max\");\n },\n /**\n * Save minimal value under the key of this user's custom properties\n * @memberof Countly.userData\n * @param {string} key - name of the property to attach to user\n * @param {number} value - value which to compare to server's value and store minimal value of both provided\n * */\n min: function(key, value) {\n log(logLevelEnums.INFO, \"[userData] min, Saving user's minimum custom property value compared to the value: [\" + value + \"] under the key: [\" + key + \"]\");\n // truncate key value pair wrt internal limits\n key = truncateSingleValue(key, self.maxKeyLength, \"userData min\", log);\n value = truncateSingleValue(value, self.maxValueSize, \"userData min\", log);\n change_custom_property(key, value, \"$min\");\n },\n /**\n * Add value to array under the key of this user's custom properties. If property is not an array, it will be converted to array\n * @memberof Countly.userData\n * @param {string} key - name of the property to attach to user\n * @param {string|number} value - value which to add to array\n * */\n push: function(key, value) {\n log(logLevelEnums.INFO, \"[userData] push, Pushing a value: [\" + value + \"] under the key: [\" + key + \"] to user's custom property array\");\n // truncate key value pair wrt internal limits\n key = truncateSingleValue(key, self.maxKeyLength, \"userData push\", log);\n value = truncateSingleValue(value, self.maxValueSize, \"userData push\", log);\n change_custom_property(key, value, \"$push\");\n },\n /**\n * Add value to array under the key of this user's custom properties, storing only unique values. If property is not an array, it will be converted to array\n * @memberof Countly.userData\n * @param {string} key - name of the property to attach to user\n * @param {string|number} value - value which to add to array\n * */\n push_unique: function(key, value) {\n log(logLevelEnums.INFO, \"[userData] push_unique, Pushing a unique value: [\" + value + \"] under the key: [\" + key + \"] to user's custom property array\");\n // truncate key value pair wrt internal limits\n key = truncateSingleValue(key, self.maxKeyLength, \"userData push_unique\", log);\n value = truncateSingleValue(value, self.maxValueSize, \"userData push_unique\", log);\n change_custom_property(key, value, \"$addToSet\");\n },\n /**\n * Remove value from array under the key of this user's custom properties\n * @memberof Countly.userData\n * @param {string} key - name of the property\n * @param {string|number} value - value which to remove from array\n * */\n pull: function(key, value) {\n log(logLevelEnums.INFO, \"[userData] pull, Removing the value: [\" + value + \"] under the key: [\" + key + \"] from user's custom property array\");\n change_custom_property(key, value, \"$pull\");\n },\n /**\n * Save changes made to user's custom properties object and send them to server\n * @memberof Countly.userData\n * */\n save: function() {\n log(logLevelEnums.INFO, \"[userData] save, Saving changes to user's custom property\");\n if (self.check_consent(featureEnums.USERS)) {\n sendEventsForced(); // flush events to event queue to prevent a drill issue\n log(logLevelEnums.INFO, \"user_details, flushed the event queue\");\n toRequestQueue({ user_details: JSON.stringify({ custom: customData }) });\n }\n customData = {};\n }\n };\n\n /**\n * Report performance trace\n * @param {Object} trace - apm trace object\n * @param {string} trace.type - device or network\n * @param {string} trace.name - url or view of the trace\n * @param {number} trace.stz - start timestamp\n * @param {number} trace.etz - end timestamp\n * @param {Object} trace.app_metrics - key/value metrics like duration, to report with trace where value is number\n * @param {Object=} trace.apm_attr - object profiling attributes (not yet supported)\n */\n this.report_trace = function(trace) {\n log(logLevelEnums.INFO, \"report_trace, Reporting performance trace\");\n if (this.check_consent(featureEnums.APM)) {\n var props = [\"type\", \"name\", \"stz\", \"etz\", \"apm_metrics\", \"apm_attr\"];\n for (var i = 0; i < props.length; i++) {\n if (props[i] !== \"apm_attr\" && typeof trace[props[i]] === \"undefined\") {\n log(logLevelEnums.WARNING, \"report_trace, APM trace don't have the property: \" + props[i]);\n return;\n }\n }\n // truncate trace name and metrics wrt internal limits\n trace.name = truncateSingleValue(trace.name, self.maxKeyLength, \"report_trace\", log);\n trace.app_metrics = truncateObject(trace.app_metrics, self.maxKeyLength, self.maxValueSize, self.maxSegmentationValues, \"report_trace\", log);\n var e = createNewObjectFromProperties(trace, props);\n e.timestamp = trace.stz;\n var date = new Date();\n e.hour = date.getHours();\n e.dow = date.getDay();\n toRequestQueue({ apm: JSON.stringify(e) });\n log(logLevelEnums.INFO, \"report_trace, Successfully adding APM trace: \", e);\n }\n };\n\n /**\n * Automatically track javascript errors that happen on the website and report them to the server\n * @param {string=} segments - additional key value pairs you want to provide with error report, like versions of libraries used, etc.\n * */\n this.track_errors = function(segments) {\n log(logLevelEnums.INFO, \"track_errors, Started tracking errors\");\n // Indicated that for this instance of the countly error tracking is enabled\n Countly.i[this.app_key].tracking_crashes = true;\n if (!window.cly_crashes) {\n window.cly_crashes = true;\n crashSegments = segments;\n // override global 'uncaught error' handler\n window.onerror = function errorBundler(msg, url, line, col, err) {\n // old browsers like IE 10 and Safari 9 won't give this value 'err' to us, but if it is provided we can trigger error recording immediately\n if (err !== undefined && err !== null) {\n // false indicates fatal error (as in non_fatal:false)\n dispatchErrors(err, false);\n }\n // fallback if no error object is present for older browsers, we create it instead\n else {\n col = col || (window.event && window.event.errorCharacter);\n var error = \"\";\n if (typeof msg !== \"undefined\") {\n error += msg + \"\\n\";\n }\n if (typeof url !== \"undefined\") {\n error += \"at \" + url;\n }\n if (typeof line !== \"undefined\") {\n error += \":\" + line;\n }\n if (typeof col !== \"undefined\") {\n error += \":\" + col;\n }\n error += \"\\n\";\n\n try {\n var stack = [];\n // deprecated, must be changed \n // eslint-disable-next-line no-caller\n var f = errorBundler.caller;\n while (f) {\n stack.push(f.name);\n f = f.caller;\n }\n error += stack.join(\"\\n\");\n }\n catch (ex) {\n log(logLevelEnums.ERROR, \"track_errors, Call stack generation experienced a problem: \" + ex);\n }\n // false indicates fatal error (as in non_fatal:false)\n dispatchErrors(error, false);\n }\n };\n\n // error handling for 'uncaught rejections'\n window.addEventListener(\"unhandledrejection\", function(event) {\n // true indicates non fatal error (as in non_fatal: true)\n dispatchErrors(new Error(\"Unhandled rejection (reason: \" + (event.reason && event.reason.stack ? event.reason.stack : event.reason) + \").\"), true);\n });\n }\n };\n\n /**\n * Log an exception that you caught through try and catch block and handled yourself and just want to report it to server\n * @param {Object} err - error exception object provided in catch block\n * @param {string=} segments - additional key value pairs you want to provide with error report, like versions of libraries used, etc.\n * */\n this.log_error = function(err, segments) {\n log(logLevelEnums.INFO, \"log_error, Logging errors\");\n // true indicates non fatal error (as in non_fatal:true)\n this.recordError(err, true, segments);\n };\n\n /**\n * Add new line in the log of breadcrumbs of what user did, will be included together with error report\n * @param {string} record - any text describing what user did\n * */\n this.add_log = function(record) {\n log(logLevelEnums.INFO, \"add_log, Adding a new log of breadcrumbs: [ \" + record + \" ]\");\n if (this.check_consent(featureEnums.CRASHES)) {\n // truncate description wrt internal limits\n record = truncateSingleValue(record, self.maxValueSize, \"add_log\", log);\n while (crashLogs.length >= self.maxBreadcrumbCount) {\n crashLogs.shift();\n log(logLevelEnums.WARNING, \"add_log, Reached maximum crashLogs size. Will erase the oldest one.\");\n }\n crashLogs.push(record);\n }\n };\n /**\n * Fetch remote config from the server (old one for method=fetch_remote_config API)\n * @param {array=} keys - Array of keys to fetch, if not provided will fetch all keys\n * @param {array=} omit_keys - Array of keys to omit, if provided will fetch all keys except provided ones\n * @param {function=} callback - Callback to notify with first param error and second param remote config object\n * */\n this.fetch_remote_config = function(keys, omit_keys, callback) {\n var keysFiltered = null;\n var omitKeysFiltered = null;\n var callbackFiltered = null;\n\n // check first param is truthy\n if (keys) {\n // if third parameter is falsy and first param is a function assign it as the callback function\n if (!callback && typeof keys === \"function\") {\n callbackFiltered = keys;\n }\n // else if first param is an array assign it as 'keys'\n else if (Array.isArray(keys)) {\n keysFiltered = keys;\n }\n }\n // check second param is truthy\n if (omit_keys) {\n // if third parameter is falsy and second param is a function assign it as the callback function\n if (!callback && typeof omit_keys === \"function\") {\n callbackFiltered = omit_keys;\n }\n // else if second param is an array assign it as 'omit_keys'\n else if (Array.isArray(omit_keys)) {\n omitKeysFiltered = omit_keys;\n }\n }\n // assign third param as a callback function if it was not assigned yet in first two params\n if (!callbackFiltered && typeof callback === \"function\") {\n callbackFiltered = callback;\n }\n\n // use new RC API\n if (this.useExplicitRcApi) {\n log(logLevelEnums.INFO, \"fetch_remote_config, Fetching remote config\");\n // opt in is true(1) or false(0)\n var opt = this.rcAutoOptinAb ? 1 : 0;\n fetch_remote_config_explicit(keysFiltered, omitKeysFiltered, opt, null, callbackFiltered);\n return;\n }\n\n log(logLevelEnums.WARNING, \"fetch_remote_config, Fetching remote config, with legacy API\");\n fetch_remote_config_explicit(keysFiltered, omitKeysFiltered, null, \"legacy\", callbackFiltered);\n };\n\n /**\n * Fetch remote config from the server (new one with method=rc API)\n * @param {array=} keys - Array of keys to fetch, if not provided will fetch all keys\n * @param {array=} omit_keys - Array of keys to omit, if provided will fetch all keys except provided ones\n * @param {number=} optIn - an inter to indicate if the user is opted in for the AB testing or not (1 is opted in, 0 is opted out)\n * @param {string=} api - which API to use, if not provided would use default (\"legacy\" is for method=\"fetch_remote_config\", default is method=\"rc\")\n * @param {function=} callback - Callback to notify with first param error and second param remote config object\n * */\n function fetch_remote_config_explicit(keys, omit_keys, optIn, api, callback) {\n log(logLevelEnums.INFO, \"fetch_remote_config_explicit, Fetching sequence initiated\");\n var request = {\n method: \"rc\",\n av: self.app_version\n };\n // check if keys were provided\n if (keys) {\n request.keys = JSON.stringify(keys);\n }\n // check if omit_keys were provided\n if (omit_keys) {\n request.omit_keys = JSON.stringify(omit_keys);\n }\n var providedCall;\n // legacy api prompt check\n if (api === \"legacy\") {\n request.method = \"fetch_remote_config\";\n }\n // opted out/in check\n if (optIn === 0) {\n request.oi = 0;\n }\n if (optIn === 1) {\n request.oi = 1;\n }\n // callback check\n if (typeof callback === \"function\") {\n providedCall = callback;\n }\n if (self.check_consent(featureEnums.SESSIONS)) {\n request.metrics = JSON.stringify(getMetrics());\n }\n if (self.check_consent(featureEnums.REMOTE_CONFIG)) {\n prepareRequest(request);\n sendXmlHttpRequest(\"fetch_remote_config_explicit\", self.url + readPath, request, function(err, params, responseText) {\n if (err) {\n log(logLevelEnums.ERROR, \"fetch_remote_config_explicit, An error occurred: \" + err);\n return;\n }\n try {\n var configs = JSON.parse(responseText);\n if (request.keys || request.omit_keys) {\n // we merge config\n for (var i in configs) {\n remoteConfigs[i] = configs[i];\n }\n }\n else {\n // we replace config\n remoteConfigs = configs;\n }\n setValueInStorage(\"cly_remote_configs\", remoteConfigs);\n }\n catch (ex) {\n log(logLevelEnums.ERROR, \"fetch_remote_config_explicit, Had an issue while parsing the response: \" + ex);\n }\n if (providedCall) {\n log(logLevelEnums.INFO, \"fetch_remote_config_explicit, Callback function is provided\");\n providedCall(err, remoteConfigs);\n }\n // JSON array can pass \n }, true);\n }\n else {\n log(logLevelEnums.ERROR, \"fetch_remote_config_explicit, Remote config requires explicit consent\");\n if (providedCall) {\n providedCall(new Error(\"Remote config requires explicit consent\"), remoteConfigs);\n }\n }\n }\n\n /**\n * AB testing key provider, opts the user in for the selected keys\n * @param {array=} keys - Array of keys opt in FOR\n * */\n this.enrollUserToAb = function(keys) {\n log(logLevelEnums.INFO, \"enrollUserToAb, Providing AB test keys to opt in for\");\n if (!keys || !Array.isArray(keys) || keys.length === 0) {\n log(logLevelEnums.ERROR, \"enrollUserToAb, No keys provided\");\n return;\n }\n var request = {\n method: \"ab\",\n keys: JSON.stringify(keys),\n av: self.app_version\n };\n prepareRequest(request);\n sendXmlHttpRequest(\"enrollUserToAb\", this.url + readPath, request, function(err, params, responseText) {\n if (err) {\n log(logLevelEnums.ERROR, \"enrollUserToAb, An error occurred: \" + err);\n return;\n }\n try {\n var resp = JSON.parse(responseText);\n log(logLevelEnums.DEBUG, \"enrollUserToAb, Parsed the response's result: [\" + resp.result + \"]\");\n }\n catch (ex) {\n log(logLevelEnums.ERROR, \"enrollUserToAb, Had an issue while parsing the response: \" + ex);\n }\n // JSON array can pass \n }, true);\n };\n\n /**\n * Gets remote config object (all key/value pairs) or specific value for provided key from the storage\n * @param {string=} key - if provided, will return value for key, or return whole object\n * @returns {object} remote configs\n * */\n this.get_remote_config = function(key) {\n log(logLevelEnums.INFO, \"get_remote_config, Getting remote config from storage\");\n if (typeof key !== \"undefined\") {\n return remoteConfigs[key];\n }\n return remoteConfigs;\n };\n\n /**\n * Stop tracking duration time for this user\n * */\n this.stop_time = function() {\n log(logLevelEnums.INFO, \"stop_time, Stopping tracking duration\");\n if (trackTime) {\n trackTime = false;\n storedDuration = getTimestamp() - lastBeat;\n lastViewStoredDuration = getTimestamp() - lastViewTime;\n }\n };\n\n /** \n * Start tracking duration time for this user, by default it is automatically tracked if you are using internal session handling\n * */\n this.start_time = function() {\n log(logLevelEnums.INFO, \"start_time, Starting tracking duration\");\n if (!trackTime) {\n trackTime = true;\n lastBeat = getTimestamp() - storedDuration;\n lastViewTime = getTimestamp() - lastViewStoredDuration;\n lastViewStoredDuration = 0;\n extendSession();\n }\n };\n\n /**\n * Track user sessions automatically, including time user spent on your website\n * */\n this.track_sessions = function() {\n log(logLevelEnums.INFO, \"track_session, Starting tracking user session\");\n // start session\n this.begin_session();\n this.start_time();\n // end session on unload\n add_event_listener(window, \"beforeunload\", function() {\n // empty the event queue\n sendEventsForced();\n self.end_session();\n });\n\n // manage sessions on window visibility events\n var hidden = \"hidden\";\n\n /**\n * Handle visibility change events\n */\n function onchange() {\n if (document[hidden] || !document.hasFocus()) {\n self.stop_time();\n }\n else {\n self.start_time();\n }\n }\n\n // add focus handling eventListeners\n add_event_listener(window, \"focus\", onchange);\n add_event_listener(window, \"blur\", onchange);\n\n // newer mobile compatible way\n add_event_listener(window, \"pageshow\", onchange);\n add_event_listener(window, \"pagehide\", onchange);\n\n // IE 9 and lower:\n if (\"onfocusin\" in document) {\n add_event_listener(window, \"focusin\", onchange);\n add_event_listener(window, \"focusout\", onchange);\n }\n\n // Page Visibility API for changing tabs and minimizing browser\n if (hidden in document) {\n document.addEventListener(\"visibilitychange\", onchange);\n }\n else if (\"mozHidden\" in document) {\n hidden = \"mozHidden\";\n document.addEventListener(\"mozvisibilitychange\", onchange);\n }\n else if (\"webkitHidden\" in document) {\n hidden = \"webkitHidden\";\n document.addEventListener(\"webkitvisibilitychange\", onchange);\n }\n else if (\"msHidden\" in document) {\n hidden = \"msHidden\";\n document.addEventListener(\"msvisibilitychange\", onchange);\n }\n\n /**\n * Reset inactivity counter and time\n */\n function resetInactivity() {\n if (inactivityCounter >= inactivityTime) {\n self.start_time();\n }\n inactivityCounter = 0;\n }\n\n add_event_listener(window, \"mousemove\", resetInactivity);\n add_event_listener(window, \"click\", resetInactivity);\n add_event_listener(window, \"keydown\", resetInactivity);\n add_event_listener(window, \"scroll\", resetInactivity);\n\n // track user inactivity\n setInterval(function() {\n inactivityCounter++;\n if (inactivityCounter >= inactivityTime) {\n self.stop_time();\n }\n }, 60000);\n };\n\n /**\n * Track page views user visits\n * @param {string=} page - optional name of the page, by default uses current url path\n * @param {array=} ignoreList - optional array of strings or regexps to test for the url/view name to ignore and not report\n * @param {object=} viewSegments - optional key value object with segments to report with the view\n * */\n this.track_pageview = function(page, ignoreList, viewSegments) {\n log(logLevelEnums.INFO, \"track_pageview, Tracking page views\");\n log(logLevelEnums.VERBOSE, \"track_pageview, last view is:[\" + lastView + \"], current view ID is:[\" + currentViewId + \"], previous view ID is:[\" + previousViewId + \"]\");\n if (lastView && trackingScrolls) {\n log(logLevelEnums.DEBUG, \"track_pageview, Scroll registry triggered\");\n processScrollView(); // for single page site's view change\n isScrollRegistryOpen = true;\n scrollRegistryTopPosition = 0;\n }\n reportViewDuration();\n previousViewId = currentViewId;\n currentViewId = secureRandom();\n // truncate page name and segmentation wrt internal limits\n page = truncateSingleValue(page, self.maxKeyLength, \"track_pageview\", log);\n // if the first parameter we got is an array we got the ignoreList first, assign it here\n if (page && Array.isArray(page)) {\n ignoreList = page;\n page = null;\n }\n // no page or ignore list provided, get the current view name/url\n if (!page) {\n page = this.getViewName();\n }\n if (page === undefined || page === \"\") {\n log(logLevelEnums.ERROR, \"track_pageview, No page name to track (it is either undefined or empty string). No page view can be tracked.\");\n return;\n }\n if (page === null) {\n log(logLevelEnums.ERROR, \"track_pageview, View name returned as null. Page view will be ignored.\");\n return;\n }\n\n if (ignoreList && ignoreList.length) {\n for (var i = 0; i < ignoreList.length; i++) {\n try {\n var reg = new RegExp(ignoreList[i]);\n if (reg.test(page)) {\n log(logLevelEnums.INFO, \"track_pageview, Ignoring the page: \" + page);\n return;\n }\n }\n catch (ex) {\n log(logLevelEnums.ERROR, \"track_pageview, Problem with finding ignore list item: \" + ignoreList[i] + \", error: \" + ex);\n }\n }\n }\n lastView = page;\n lastViewTime = getTimestamp();\n log(logLevelEnums.VERBOSE, \"track_pageview, last view is assigned:[\" + lastView + \"], current view ID is:[\" + currentViewId + \"], previous view ID is:[\" + previousViewId + \"]\");\n var segments = {\n name: page,\n visit: 1,\n view: self.getViewUrl()\n };\n // truncate new segment\n segments = truncateObject(segments, self.maxKeyLength, self.maxValueSize, self.maxSegmentationValues, \"track_pageview\", log);\n if (this.track_domains) {\n segments.domain = window.location.hostname;\n }\n\n if (useSessionCookie) {\n if (!sessionStarted) {\n // tracking view was called before tracking session, so we check expiration ourselves\n var expire = getValueFromStorage(\"cly_session\");\n if (!expire || parseInt(expire) <= getTimestamp()) {\n firstView = false;\n segments.start = 1;\n }\n }\n // tracking views called after tracking session, so we can rely on tracking session decision\n else if (firstView) {\n firstView = false;\n segments.start = 1;\n }\n }\n // if we are not using session cookie, there is no session state between refreshes\n // so we fallback to old logic of landing\n else if (typeof document.referrer !== \"undefined\" && document.referrer.length) {\n var matches = urlParseRE.exec(document.referrer);\n // do not report referrers of current website\n if (matches && matches[11] && matches[11] !== window.location.hostname) {\n segments.start = 1;\n }\n }\n\n // add utm tags\n if (freshUTMTags && Object.keys(freshUTMTags).length) {\n log(logLevelEnums.INFO, \"track_pageview, Adding fresh utm tags to segmentation:[\" + JSON.stringify(freshUTMTags) + \"]\");\n for (var utm in freshUTMTags) {\n if (typeof segments[\"utm_\" + utm] === \"undefined\") {\n segments[\"utm_\" + utm] = freshUTMTags[utm];\n }\n }\n // TODO: Current logic adds utm tags to each view if the user landed with utm tags for that session(in non literal sense)\n // we might want to change this logic to add utm tags only to the first view's segmentation by freshUTMTags = null; here\n }\n\n // add referrer if it is usable\n if (isReferrerUsable()) {\n log(logLevelEnums.INFO, \"track_pageview, Adding referrer to segmentation:[\" + document.referrer + \"]\");\n segments.referrer = document.referrer; // add referrer\n }\n\n if (viewSegments) {\n viewSegments = truncateObject(viewSegments, self.maxKeyLength, self.maxValueSize, self.maxSegmentationValues, \"track_pageview\", log);\n\n for (var key in viewSegments) {\n if (typeof segments[key] === \"undefined\") {\n segments[key] = viewSegments[key];\n }\n }\n }\n\n // track pageview\n if (this.check_consent(featureEnums.VIEWS)) {\n add_cly_events({\n key: internalEventKeyEnums.VIEW,\n segmentation: segments\n }, currentViewId);\n }\n else {\n lastParams.track_pageview = arguments;\n }\n };\n\n /**\n * Track page views user visits. Alias of {@link track_pageview} method for compatibility with NodeJS SDK\n * @param {string=} page - optional name of the page, by default uses current url path\n * @param {array=} ignoreList - optional array of strings or regexps to test for the url/view name to ignore and not report\n * @param {object=} segments - optional view segments to track with the view\n * */\n this.track_view = function(page, ignoreList, segments) {\n log(logLevelEnums.INFO, \"track_view, Initiating tracking page views\");\n this.track_pageview(page, ignoreList, segments);\n };\n\n /**\n * Track all clicks on this page\n * @param {Object=} parent - DOM object which children to track, by default it is document body\n * */\n this.track_clicks = function(parent) {\n log(logLevelEnums.INFO, \"track_clicks, Starting to track clicks\");\n if (parent) {\n log(logLevelEnums.INFO, \"track_clicks, Tracking the specified children:[\" + parent + \"]\");\n }\n parent = parent || document;\n var shouldProcess = true;\n /**\n * Process click information\n * @param {Event} event - click event\n */\n function processClick(event) {\n if (shouldProcess) {\n shouldProcess = false;\n\n // cross browser click coordinates\n get_page_coord(event);\n if (typeof event.pageX !== \"undefined\" && typeof event.pageY !== \"undefined\") {\n var height = getDocHeight();\n var width = getDocWidth();\n\n // record click event\n if (self.check_consent(featureEnums.CLICKS)) {\n var segments = {\n type: \"click\",\n x: event.pageX,\n y: event.pageY,\n width: width,\n height: height,\n view: self.getViewUrl()\n };\n // truncate new segment\n segments = truncateObject(segments, self.maxKeyLength, self.maxValueSize, self.maxSegmentationValues, \"processClick\", log);\n if (self.track_domains) {\n segments.domain = window.location.hostname;\n }\n add_cly_events({\n key: internalEventKeyEnums.ACTION,\n segmentation: segments\n });\n }\n }\n setTimeout(function() {\n shouldProcess = true;\n }, 1000);\n }\n }\n // add any events you want\n add_event_listener(parent, \"click\", processClick);\n };\n\n /**\n * Track all scrolls on this page\n * @param {Object=} parent - DOM object which children to track, by default it is document body\n * */\n this.track_scrolls = function(parent) {\n log(logLevelEnums.INFO, \"track_scrolls, Starting to track scrolls\");\n if (parent) {\n log(logLevelEnums.INFO, \"track_scrolls, Tracking the specified children\");\n }\n parent = parent || window;\n isScrollRegistryOpen = true;\n trackingScrolls = true;\n\n add_event_listener(parent, \"scroll\", processScroll);\n add_event_listener(parent, \"beforeunload\", processScrollView);\n };\n\n /**\n * Generate custom event for all links that were clicked on this page\n * @param {Object=} parent - DOM object which children to track, by default it is document body\n * */\n this.track_links = function(parent) {\n log(logLevelEnums.INFO, \"track_links, Starting to track clicks to links\");\n if (parent) {\n log(logLevelEnums.INFO, \"track_links, Tracking the specified children\");\n }\n parent = parent || document;\n /**\n * Process click information\n * @param {Event} event - click event\n */\n function processClick(event) {\n // get element which was clicked\n var elem = get_closest_element(get_event_target(event), \"a\");\n\n if (elem) {\n // cross browser click coordinates\n get_page_coord(event);\n\n // record click event\n if (self.check_consent(featureEnums.CLICKS)) {\n add_cly_events({\n key: \"linkClick\",\n segmentation: {\n href: elem.href,\n text: elem.innerText,\n id: elem.id,\n view: self.getViewUrl()\n }\n });\n }\n }\n }\n\n // add any events you want\n add_event_listener(parent, \"click\", processClick);\n };\n\n /**\n * Generate custom event for all forms that were submitted on this page\n * @param {Object=} parent - DOM object which children to track, by default it is document body\n * @param {boolean=} trackHidden - provide true to also track hidden inputs, default false\n * */\n this.track_forms = function(parent, trackHidden) {\n log(logLevelEnums.INFO, \"track_forms, Starting to track form submissions. DOM object provided:[\" + (!!parent) + \"] Tracking hidden inputs :[\" + (!!trackHidden) + \"]\");\n parent = parent || document;\n /**\n * Get name of the input\n * @param {HTMLElement} input - HTML input from which to get name\n * @returns {String} name of the input\n */\n function getInputName(input) {\n return input.name || input.id || input.type || input.nodeName;\n }\n /**\n * Process form data\n * @param {Event} event - form submission event\n */\n function processForm(event) {\n var form = get_event_target(event);\n var segmentation = {\n id: form.attributes.id && form.attributes.id.nodeValue,\n name: form.attributes.name && form.attributes.name.nodeValue,\n action: form.attributes.action && form.attributes.action.nodeValue,\n method: form.attributes.method && form.attributes.method.nodeValue,\n view: self.getViewUrl()\n };\n\n // get input values\n var input;\n if (typeof form.elements !== \"undefined\") {\n for (var i = 0; i < form.elements.length; i++) {\n input = form.elements[i];\n if (input && input.type !== \"password\" && input.className.indexOf(\"cly_user_ignore\") === -1) {\n if (typeof segmentation[\"input:\" + getInputName(input)] === \"undefined\") {\n segmentation[\"input:\" + getInputName(input)] = [];\n }\n if (input.nodeName.toLowerCase() === \"select\") {\n if (typeof input.multiple !== \"undefined\") {\n segmentation[\"input:\" + getInputName(input)].push(getMultiSelectValues(input));\n }\n else {\n segmentation[\"input:\" + getInputName(input)].push(input.options[input.selectedIndex].value);\n }\n }\n else if (input.nodeName.toLowerCase() === \"input\") {\n if (typeof input.type !== \"undefined\") {\n if (input.type.toLowerCase() === \"checkbox\" || input.type.toLowerCase() === \"radio\") {\n if (input.checked) {\n segmentation[\"input:\" + getInputName(input)].push(input.value);\n }\n }\n else if (input.type.toLowerCase() !== \"hidden\" || trackHidden) {\n segmentation[\"input:\" + getInputName(input)].push(input.value);\n }\n }\n else {\n segmentation[\"input:\" + getInputName(input)].push(input.value);\n }\n }\n else if (input.nodeName.toLowerCase() === \"textarea\") {\n segmentation[\"input:\" + getInputName(input)].push(input.value);\n }\n else if (typeof input.value !== \"undefined\") {\n segmentation[\"input:\" + getInputName(input)].push(input.value);\n }\n }\n }\n for (var key in segmentation) {\n if (segmentation[key] && typeof segmentation[key].join === \"function\") {\n segmentation[key] = segmentation[key].join(\", \");\n }\n }\n }\n\n // record submit event\n if (self.check_consent(featureEnums.FORMS)) {\n add_cly_events({\n key: \"formSubmit\",\n segmentation: segmentation\n });\n }\n }\n\n // add any events you want\n add_event_listener(parent, \"submit\", processForm);\n };\n\n /**\n * Collect possible user data from submitted forms. Add cly_user_ignore class to ignore inputs in forms or cly_user_{key} to collect data from this input as specified key, as cly_user_username to save collected value from this input as username property. If not class is provided, Countly SDK will try to determine type of information automatically.\n * @param {Object=} parent - DOM object which children to track, by default it is document body\n * @param {boolean} [useCustom=false] - submit collected data as custom user properties, by default collects as main user properties\n * */\n this.collect_from_forms = function(parent, useCustom) {\n log(logLevelEnums.INFO, \"collect_from_forms, Starting to collect possible user data. DOM object provided:[\" + (!!parent) + \"] Submitting custom user property:[\" + (!!useCustom) + \"]\");\n parent = parent || document;\n /**\n * Process form data\n * @param {Event} event - form submission event\n */\n function processForm(event) {\n var form = get_event_target(event);\n var userdata = {};\n var hasUserInfo = false;\n\n // get input values\n var input;\n if (typeof form.elements !== \"undefined\") {\n // load labels for inputs\n var labelData = {};\n var labels = parent.getElementsByTagName(\"LABEL\");\n var i;\n var j;\n for (i = 0; i < labels.length; i++) {\n if (labels[i].htmlFor && labels[i].htmlFor !== \"\") {\n labelData[labels[i].htmlFor] = labels[i].innerText || labels[i].textContent || labels[i].innerHTML;\n }\n }\n for (i = 0; i < form.elements.length; i++) {\n input = form.elements[i];\n if (input && input.type !== \"password\") {\n // check if element should be ignored\n if (input.className.indexOf(\"cly_user_ignore\") === -1) {\n var value = \"\";\n // get value from input\n if (input.nodeName.toLowerCase() === \"select\") {\n if (typeof input.multiple !== \"undefined\") {\n value = getMultiSelectValues(input);\n }\n else {\n value = input.options[input.selectedIndex].value;\n }\n }\n else if (input.nodeName.toLowerCase() === \"input\") {\n if (typeof input.type !== \"undefined\") {\n if (input.type.toLowerCase() === \"checkbox\" || input.type.toLowerCase() === \"radio\") {\n if (input.checked) {\n value = input.value;\n }\n }\n else {\n value = input.value;\n }\n }\n else {\n value = input.value;\n }\n }\n else if (input.nodeName.toLowerCase() === \"textarea\") {\n value = input.value;\n }\n else if (typeof input.value !== \"undefined\") {\n value = input.value;\n }\n // check if input was marked to be collected\n if (input.className && input.className.indexOf(\"cly_user_\") !== -1) {\n var classes = input.className.split(\" \");\n for (j = 0; j < classes.length; j++) {\n if (classes[j].indexOf(\"cly_user_\") === 0) {\n userdata[classes[j].replace(\"cly_user_\", \"\")] = value;\n hasUserInfo = true;\n break;\n }\n }\n }\n // check for email\n else if ((input.type && input.type.toLowerCase() === \"email\")\n || (input.name && input.name.toLowerCase().indexOf(\"email\") !== -1)\n || (input.id && input.id.toLowerCase().indexOf(\"email\") !== -1)\n || (input.id && labelData[input.id] && labelData[input.id].toLowerCase().indexOf(\"email\") !== -1)\n || (/[^@\\s]+@[^@\\s]+\\.[^@\\s]+/).test(value)) {\n if (!userdata.email) {\n userdata.email = value;\n }\n hasUserInfo = true;\n }\n else if ((input.name && input.name.toLowerCase().indexOf(\"username\") !== -1)\n || (input.id && input.id.toLowerCase().indexOf(\"username\") !== -1)\n || (input.id && labelData[input.id] && labelData[input.id].toLowerCase().indexOf(\"username\") !== -1)) {\n if (!userdata.username) {\n userdata.username = value;\n }\n hasUserInfo = true;\n }\n else if ((input.name && (input.name.toLowerCase().indexOf(\"tel\") !== -1 || input.name.toLowerCase().indexOf(\"phone\") !== -1 || input.name.toLowerCase().indexOf(\"number\") !== -1))\n || (input.id && (input.id.toLowerCase().indexOf(\"tel\") !== -1 || input.id.toLowerCase().indexOf(\"phone\") !== -1 || input.id.toLowerCase().indexOf(\"number\") !== -1))\n || (input.id && labelData[input.id] && (labelData[input.id].toLowerCase().indexOf(\"tel\") !== -1 || labelData[input.id].toLowerCase().indexOf(\"phone\") !== -1 || labelData[input.id].toLowerCase().indexOf(\"number\") !== -1))) {\n if (!userdata.phone) {\n userdata.phone = value;\n }\n hasUserInfo = true;\n }\n else if ((input.name && (input.name.toLowerCase().indexOf(\"org\") !== -1 || input.name.toLowerCase().indexOf(\"company\") !== -1))\n || (input.id && (input.id.toLowerCase().indexOf(\"org\") !== -1 || input.id.toLowerCase().indexOf(\"company\") !== -1))\n || (input.id && labelData[input.id] && (labelData[input.id].toLowerCase().indexOf(\"org\") !== -1 || labelData[input.id].toLowerCase().indexOf(\"company\") !== -1))) {\n if (!userdata.organization) {\n userdata.organization = value;\n }\n hasUserInfo = true;\n }\n else if ((input.name && input.name.toLowerCase().indexOf(\"name\") !== -1)\n || (input.id && input.id.toLowerCase().indexOf(\"name\") !== -1)\n || (input.id && labelData[input.id] && labelData[input.id].toLowerCase().indexOf(\"name\") !== -1)) {\n if (!userdata.name) {\n userdata.name = \"\";\n }\n userdata.name += value + \" \";\n hasUserInfo = true;\n }\n }\n }\n }\n }\n\n // record user info, if any\n if (hasUserInfo) {\n log(logLevelEnums.INFO, \"collect_from_forms, Gathered user data\", userdata);\n if (useCustom) {\n self.user_details({ custom: userdata });\n }\n else {\n self.user_details(userdata);\n }\n }\n }\n\n // add any events you want\n add_event_listener(parent, \"submit\", processForm);\n };\n\n /**\n * Collect information about user from Facebook, if your website integrates Facebook SDK. Call this method after Facebook SDK is loaded and user is authenticated.\n * @param {Object=} custom - Custom keys to collected from Facebook, key will be used to store as key in custom user properties and value as key in Facebook graph object. For example, {\"tz\":\"timezone\"} will collect Facebook's timezone property, if it is available and store it in custom user's property under \"tz\" key. If you want to get value from some sub object properties, then use dot as delimiter, for example, {\"location\":\"location.name\"} will collect data from Facebook's {\"location\":{\"name\":\"MyLocation\"}} object and store it in user's custom property \"location\" key\n * */\n this.collect_from_facebook = function(custom) {\n if (typeof FB === \"undefined\" || !FB || !FB.api) {\n log(logLevelEnums.ERROR, \"collect_from_facebook, Facebook SDK is not available\");\n return;\n }\n log(logLevelEnums.INFO, \"collect_from_facebook, Starting to collect possible user data\");\n /* globals FB */\n FB.api(\"/me\", function(resp) {\n var data = {};\n if (resp.name) {\n data.name = resp.name;\n }\n if (resp.email) {\n data.email = resp.email;\n }\n if (resp.gender === \"male\") {\n data.gender = \"M\";\n }\n else if (resp.gender === \"female\") {\n data.gender = \"F\";\n }\n if (resp.birthday) {\n var byear = resp.birthday.split(\"/\").pop();\n if (byear && byear.length === 4) {\n data.byear = byear;\n }\n }\n if (resp.work && resp.work[0] && resp.work[0].employer && resp.work[0].employer.name) {\n data.organization = resp.work[0].employer.name;\n }\n // check if any custom keys to collect\n if (custom) {\n data.custom = {};\n for (var i in custom) {\n var parts = custom[i].split(\".\");\n var get = resp;\n for (var j = 0; j < parts.length; j++) {\n get = get[parts[j]];\n if (typeof get === \"undefined\") {\n break;\n }\n }\n if (typeof get !== \"undefined\") {\n data.custom[i] = get;\n }\n }\n }\n self.user_details(data);\n });\n };\n /**\n * Opts out user of any metric tracking\n * */\n this.opt_out = function() {\n log(logLevelEnums.INFO, \"opt_out, Opting out the user\");\n this.ignore_visitor = true;\n setValueInStorage(\"cly_ignore\", true);\n };\n\n /**\n * Opts in user for tracking, if complies with other user ignore rules like bot useragent and prefetch settings\n * */\n this.opt_in = function() {\n log(logLevelEnums.INFO, \"opt_in, Opting in the user\");\n setValueInStorage(\"cly_ignore\", false);\n this.ignore_visitor = false;\n checkIgnore();\n if (!this.ignore_visitor && !hasPulse) {\n heartBeat();\n }\n };\n /**\n * Provide information about user\n * @param {Object} ratingWidget - object with rating widget properties\n * @param {string} ratingWidget.widget_id - id of the widget in the dashboard\n * @param {boolean=} ratingWidget.contactMe - did user give consent to contact him\n * @param {string=} ratingWidget.platform - user's platform (will be filled if not provided)\n * @param {string=} ratingWidget.app_version - app's app version (will be filled if not provided)\n * @param {number} ratingWidget.rating - user's rating from 1 to 5\n * @param {string=} ratingWidget.email - user's email\n * @param {string=} ratingWidget.comment - user's comment\n * \n * @deprecated use 'recordRatingWidgetWithID' in place of this call\n * */\n this.report_feedback = function(ratingWidget) {\n log(logLevelEnums.WARNING, \"report_feedback, Deprecated function call! Use 'recordRatingWidgetWithID' or 'reportFeedbackWidgetManually' in place of this call. Call will be redirected to 'recordRatingWidgetWithID' now!\");\n this.recordRatingWidgetWithID(ratingWidget);\n };\n /**\n * Provide information about user\n * @param {Object} ratingWidget - object with rating widget properties\n * @param {string} ratingWidget.widget_id - id of the widget in the dashboard\n * @param {boolean=} ratingWidget.contactMe - did user give consent to contact him\n * @param {string=} ratingWidget.platform - user's platform (will be filled if not provided)\n * @param {string=} ratingWidget.app_version - app's app version (will be filled if not provided)\n * @param {number} ratingWidget.rating - user's rating from 1 to 5\n * @param {string=} ratingWidget.email - user's email\n * @param {string=} ratingWidget.comment - user's comment\n * */\n this.recordRatingWidgetWithID = function(ratingWidget) {\n log(logLevelEnums.INFO, \"recordRatingWidgetWithID, Providing information about user with ID: [ \" + ratingWidget.widget_id + \" ]\");\n if (!this.check_consent(featureEnums.STAR_RATING)) {\n return;\n }\n if (!ratingWidget.widget_id) {\n log(logLevelEnums.ERROR, \"recordRatingWidgetWithID, Rating Widget must contain widget_id property\");\n return;\n }\n if (!ratingWidget.rating) {\n log(logLevelEnums.ERROR, \"recordRatingWidgetWithID, Rating Widget must contain rating property\");\n return;\n }\n var props = [\"widget_id\", \"contactMe\", \"platform\", \"app_version\", \"rating\", \"email\", \"comment\"];\n var event = {\n key: internalEventKeyEnums.STAR_RATING,\n count: 1,\n segmentation: {}\n };\n event.segmentation = createNewObjectFromProperties(ratingWidget, props);\n if (!event.segmentation.app_version) {\n event.segmentation.app_version = this.metrics._app_version || this.app_version;\n }\n if (event.segmentation.rating > 5) {\n log(logLevelEnums.WARNING, \"recordRatingWidgetWithID, You have entered a rating higher than 5. Changing it back to 5 now.\");\n event.segmentation.rating = 5;\n }\n else if (event.segmentation.rating < 1) {\n log(logLevelEnums.WARNING, \"recordRatingWidgetWithID, You have entered a rating lower than 1. Changing it back to 1 now.\");\n event.segmentation.rating = 1;\n }\n log(logLevelEnums.INFO, \"recordRatingWidgetWithID, Reporting Rating Widget: \", event);\n add_cly_events(event);\n };\n /**\n * Report information about survey, nps or rating widget answers/results\n * @param {Object} CountlyFeedbackWidget - it is the widget object retrieved from get_available_feedback_widgets\n * @param {Object} CountlyWidgetData - it is the widget data object retrieved from getFeedbackWidgetData\n * @param {Object} widgetResult - it is the widget results that need to be reported, different for all widgets, if provided as null it means the widget was closed\n * widgetResult For NPS\n * Should include rating and comment from the nps. Example:\n * widgetResult = {rating: 3, comment: \"comment\"}\n * \n * widgetResult For Survey\n * Should include questions ids and their answers as key/value pairs. Keys should be formed as “answ-”+[question.id]. Example:\n * widgetResult = {\n * \"answ-1602694029-0\": \"Some text field long answer\", //for text fields\n * \"answ-1602694029-1\": 7, //for rating\n * \"answ-1602694029-2\": \"ch1602694029-0\", //There is a question with choices like multi or radio. It is a choice key.\n * \"answ-1602694029-3\": \"ch1602694030-0,ch1602694030-1\" //In case 2 selected\n * }\n * \n * widgetResult For Rating Widget\n * Should include rating, email, comment and contact consent information. Example:\n * widgetResult = {\n * rating: 2, \n * email: \"email@mail.com\", \n * contactMe: true, \n * comment: \"comment\"\n * }\n * */\n this.reportFeedbackWidgetManually = function(CountlyFeedbackWidget, CountlyWidgetData, widgetResult) {\n if (!this.check_consent(featureEnums.FEEDBACK)) {\n return;\n }\n if (!(CountlyFeedbackWidget && CountlyWidgetData)) {\n log(logLevelEnums.ERROR, \"reportFeedbackWidgetManually, Widget data and/or Widget object not provided. Aborting.\");\n return;\n }\n if (!CountlyFeedbackWidget._id) {\n log(logLevelEnums.ERROR, \"reportFeedbackWidgetManually, Feedback Widgets must contain _id property\");\n return;\n }\n if (offlineMode) {\n log(logLevelEnums.ERROR, \"reportFeedbackWidgetManually, Feedback Widgets can not be reported in offline mode\");\n return;\n }\n\n log(logLevelEnums.INFO, \"reportFeedbackWidgetManually, Providing information about user with, provided result of the widget with ID: [ \" + CountlyFeedbackWidget._id + \" ] and type: [\" + CountlyFeedbackWidget.type + \"]\");\n\n // type specific checks to see if everything was provided\n var props = [];\n var type = CountlyFeedbackWidget.type;\n var eventKey;\n if (type === \"nps\") {\n if (widgetResult) {\n if (!widgetResult.rating) {\n log(logLevelEnums.ERROR, \"reportFeedbackWidgetManually, Widget must contain rating property\");\n return;\n }\n widgetResult.rating = Math.round(widgetResult.rating);\n if (widgetResult.rating > 10) {\n log(logLevelEnums.WARNING, \"reportFeedbackWidgetManually, You have entered a rating higher than 10. Changing it back to 10 now.\");\n widgetResult.rating = 10;\n }\n else if (widgetResult.rating < 0) {\n log(logLevelEnums.WARNING, \"reportFeedbackWidgetManually, You have entered a rating lower than 0. Changing it back to 0 now.\");\n widgetResult.rating = 0;\n }\n props = [\"rating\", \"comment\"];\n }\n eventKey = internalEventKeyEnums.NPS;\n }\n else if (type === \"survey\") {\n if (widgetResult) {\n if (Object.keys(widgetResult).length < 1) {\n log(logLevelEnums.ERROR, \"reportFeedbackWidgetManually, Widget should have answers to be reported\");\n return;\n }\n props = Object.keys(widgetResult);\n }\n eventKey = internalEventKeyEnums.SURVEY;\n }\n else if (type === \"rating\") {\n if (widgetResult) {\n if (!widgetResult.rating) {\n log(logLevelEnums.ERROR, \"reportFeedbackWidgetManually, Widget must contain rating property\");\n return;\n }\n widgetResult.rating = Math.round(widgetResult.rating);\n if (widgetResult.rating > 5) {\n log(logLevelEnums.WARNING, \"reportFeedbackWidgetManually, You have entered a rating higher than 5. Changing it back to 5 now.\");\n widgetResult.rating = 5;\n }\n else if (widgetResult.rating < 1) {\n log(logLevelEnums.WARNING, \"reportFeedbackWidgetManually, You have entered a rating lower than 1. Changing it back to 1 now.\");\n widgetResult.rating = 1;\n }\n props = [\"rating\", \"comment\", \"email\", \"contactMe\"];\n }\n eventKey = internalEventKeyEnums.STAR_RATING;\n }\n else {\n log(logLevelEnums.ERROR, \"reportFeedbackWidgetManually, Widget has an unacceptable type\");\n return;\n }\n\n // event template\n var event = {\n key: eventKey,\n count: 1,\n segmentation: {\n widget_id: CountlyFeedbackWidget._id,\n platform: this.platform,\n app_version: this.metrics._app_version || this.app_version\n }\n };\n\n if (widgetResult === null) {\n event.segmentation.closed = 1;\n }\n else {\n // add response to the segmentation\n event.segmentation = addNewProperties(event.segmentation, widgetResult, props);\n }\n\n // add event\n log(logLevelEnums.INFO, \"reportFeedbackWidgetManually, Reporting \" + type + \": \", event);\n add_cly_events(event);\n };\n /**\n * Show specific widget popup by the widget id\n * @param {string} id - id value of related rating widget, you can get this value by click \"Copy ID\" button in row menu at \"Feedback widgets\" screen\n * \n * @deprecated use 'presentRatingWidgetWithID' in place of this call\n */\n this.show_feedback_popup = function(id) {\n log(logLevelEnums.WARNING, \"show_feedback_popup, Deprecated function call! Use 'presentRatingWidgetWithID' in place of this call. Call will be redirected now!\");\n this.presentRatingWidgetWithID(id);\n };\n /**\n * Show specific widget popup by the widget id\n * @param {string} id - id value of related rating widget, you can get this value by click \"Copy ID\" button in row menu at \"Feedback widgets\" screen\n */\n this.presentRatingWidgetWithID = function(id) {\n log(logLevelEnums.INFO, \"presentRatingWidgetWithID, Showing rating widget popup for the widget with ID: [ \" + id + \" ]\");\n if (!this.check_consent(featureEnums.STAR_RATING)) {\n return;\n }\n if (offlineMode) {\n log(logLevelEnums.ERROR, \"presentRatingWidgetWithID, Cannot show ratingWidget popup in offline mode\");\n }\n else {\n sendXmlHttpRequest(\"presentRatingWidgetWithID,\", this.url + \"/o/feedback/widget\", { widget_id: id, av: self.app_version }, function(err, params, responseText) {\n if (err) {\n log(logLevelEnums.ERROR, \"presentRatingWidgetWithID, An error occurred: \" + err);\n return;\n }\n try {\n // widget object\n var currentWidget = JSON.parse(responseText);\n processWidget(currentWidget, false);\n }\n catch (JSONParseError) {\n log(logLevelEnums.ERROR, \"presentRatingWidgetWithID, JSON parse failed: \" + JSONParseError);\n }\n // JSON array can pass \n }, true);\n }\n };\n\n /**\n * Prepare rating widgets according to the current options\n * @param {array=} enableWidgets - widget ids array\n * \n * @deprecated use 'initializeRatingWidgets' in place of this call\n */\n this.initialize_feedback_popups = function(enableWidgets) {\n log(logLevelEnums.WARNING, \"initialize_feedback_popups, Deprecated function call! Use 'initializeRatingWidgets' in place of this call. Call will be redirected now!\");\n this.initializeRatingWidgets(enableWidgets);\n };\n /**\n * Prepare rating widgets according to the current options\n * @param {array=} enableWidgets - widget ids array\n */\n this.initializeRatingWidgets = function(enableWidgets) {\n log(logLevelEnums.INFO, \"initializeRatingWidgets, Initializing rating widget with provided widget IDs:[ \" + enableWidgets + \"]\");\n if (!this.check_consent(featureEnums.STAR_RATING)) {\n return;\n }\n if (!enableWidgets) {\n enableWidgets = getValueFromStorage(\"cly_fb_widgets\");\n }\n\n // remove all old stickers before add new one\n var stickers = document.getElementsByClassName(\"countly-feedback-sticker\");\n while (stickers.length > 0) {\n stickers[0].remove();\n }\n\n sendXmlHttpRequest(\"initializeRatingWidgets,\", this.url + \"/o/feedback/multiple-widgets-by-id\", { widgets: JSON.stringify(enableWidgets), av: self.app_version }, function(err, params, responseText) {\n if (err) {\n log(logLevelEnums.ERROR, \"initializeRatingWidgets, An error occurred: \" + err);\n return;\n }\n try {\n // widgets array\n var widgets = JSON.parse(responseText);\n for (var i = 0; i < widgets.length; i++) {\n if (widgets[i].is_active === \"true\") {\n var target_devices = widgets[i].target_devices;\n var currentDevice = userAgentDeviceDetection();\n // device match check\n if (target_devices[currentDevice]) {\n // is hide sticker option selected?\n if (typeof widgets[i].hide_sticker === \"string\") {\n widgets[i].hide_sticker = widgets[i].hide_sticker === \"true\";\n }\n // is target_page option provided as \"All\"?\n if (widgets[i].target_page === \"all\" && !widgets[i].hide_sticker) {\n processWidget(widgets[i], true);\n }\n // is target_page option provided as \"selected\"?\n else {\n var pages = widgets[i].target_pages;\n for (var k = 0; k < pages.length; k++) {\n var isWildcardMatched = pages[k].substr(0, pages[k].length - 1) === window.location.pathname.substr(0, pages[k].length - 1);\n var isFullPathMatched = pages[k] === window.location.pathname;\n var isContainAsterisk = pages[k].includes(\"*\");\n if (((isContainAsterisk && isWildcardMatched) || isFullPathMatched) && !widgets[i].hide_sticker) {\n processWidget(widgets[i], true);\n }\n }\n }\n }\n }\n }\n }\n catch (JSONParseError) {\n log(logLevelEnums.ERROR, \"initializeRatingWidgets, JSON parse error: \" + JSONParseError);\n }\n // JSON array can pass\n }, true);\n };\n\n /**\n * Show rating widget popup by passed widget ids array\n * @param {object=} params - required - includes \"popups\" property as string array of widgets (\"widgets\" for old versions)\n * example params: {\"popups\":[\"5b21581b967c4850a7818617\"]}\n * \n * @deprecated use 'enableRatingWidgets' in place of this call\n * */\n this.enable_feedback = function(params) {\n log(logLevelEnums.WARNING, \"enable_feedback, Deprecated function call! Use 'enableRatingWidgets' in place of this call. Call will be redirected now!\");\n this.enableRatingWidgets(params);\n };\n /**\n * Show rating widget popup by passed widget ids array\n * @param {object=} params - required - includes \"popups\" property as string array of widgets (\"widgets\" for old versions)\n * example params: {\"popups\":[\"5b21581b967c4850a7818617\"]}\n * */\n this.enableRatingWidgets = function(params) {\n log(logLevelEnums.INFO, \"enableRatingWidgets, Enabling rating widget with params:\", params);\n if (!this.check_consent(featureEnums.STAR_RATING)) {\n return;\n }\n if (offlineMode) {\n log(logLevelEnums.ERROR, \"enableRatingWidgets, Cannot enable rating widgets in offline mode\");\n }\n else {\n setValueInStorage(\"cly_fb_widgets\", params.popups || params.widgets);\n // inject feedback styles\n loadCSS(this.url + \"/star-rating/stylesheets/countly-feedback-web.css\");\n // get enable widgets by app_key\n // define xhr object\n var enableWidgets = params.popups || params.widgets;\n\n if (enableWidgets.length > 0) {\n document.body.insertAdjacentHTML(\"beforeend\", \"\");\n this.initializeRatingWidgets(enableWidgets);\n }\n else {\n log(logLevelEnums.ERROR, \"enableRatingWidgets, You should provide at least one widget id as param. Read documentation for more detail. https://resources.count.ly/plugins/feedback\");\n }\n }\n };\n\n /**\n * This function retrieves all associated widget information (IDs, type, name etc in an array/list of objects) of your app\n * @param {Function} callback - Callback function with two parameters, 1st for returned list, 2nd for error\n * */\n this.get_available_feedback_widgets = function(callback) {\n log(logLevelEnums.INFO, \"get_available_feedback_widgets, Getting the feedback list, callback function is provided:[\" + (!!callback) + \"]\");\n if (!this.check_consent(featureEnums.FEEDBACK)) {\n if (callback) {\n callback(null, new Error(\"Consent for feedback not provided.\"));\n }\n return;\n }\n\n if (offlineMode) {\n log(logLevelEnums.ERROR, \"get_available_feedback_widgets, Cannot enable feedback widgets in offline mode.\");\n return;\n }\n\n var url = this.url + readPath;\n var data = {\n method: featureEnums.FEEDBACK,\n device_id: this.device_id,\n app_key: this.app_key,\n av: self.app_version\n };\n\n sendXmlHttpRequest(\"get_available_feedback_widgets,\", url, data, function(err, params, responseText) {\n if (err) {\n log(logLevelEnums.ERROR, \"get_available_feedback_widgets, Error occurred while fetching feedbacks: \" + err);\n if (callback) {\n callback(null, err);\n }\n return;\n }\n\n try {\n var response = JSON.parse(responseText);\n var feedbacks = response.result || [];\n if (callback) {\n callback(feedbacks, null);\n }\n }\n catch (error) {\n log(logLevelEnums.ERROR, \"get_available_feedback_widgets, Error while parsing feedback widgets list: \" + error);\n if (callback) {\n callback(null, error);\n }\n }\n // expected response is JSON object\n }, false);\n };\n\n /**\n * Get feedback (nps, survey or rating) widget data, like questions, message etc.\n * @param {Object} CountlyFeedbackWidget - Widget object, retrieved from 'get_available_feedback_widgets'\n * @param {Function} callback - Callback function with two parameters, 1st for returned widget data, 2nd for error\n * */\n this.getFeedbackWidgetData = function(CountlyFeedbackWidget, callback) {\n if (!CountlyFeedbackWidget.type) {\n log(logLevelEnums.ERROR, \"getFeedbackWidgetData, Expected the provided widget object to have a type but got: [\" + JSON.stringify(CountlyFeedbackWidget) + \"], aborting.\");\n return;\n }\n log(logLevelEnums.INFO, \"getFeedbackWidgetData, Retrieving data for: [\" + JSON.stringify(CountlyFeedbackWidget) + \"], callback function is provided:[\" + (!!callback) + \"]\");\n if (!this.check_consent(featureEnums.FEEDBACK)) {\n if (callback) {\n callback(null, new Error(\"Consent for feedback not provided.\"));\n }\n return;\n }\n\n if (offlineMode) {\n log(logLevelEnums.ERROR, \"getFeedbackWidgetData, Cannot enable feedback widgets in offline mode.\");\n return;\n }\n\n var url = this.url;\n var data = {\n widget_id: CountlyFeedbackWidget._id,\n shown: 1,\n sdk_version: SDK_VERSION,\n sdk_name: SDK_NAME,\n platform: this.platform,\n app_version: this.app_version\n };\n\n if (CountlyFeedbackWidget.type === \"nps\") {\n url += \"/o/surveys/nps/widget\";\n }\n else if (CountlyFeedbackWidget.type === \"survey\") {\n url += \"/o/surveys/survey/widget\";\n }\n else if (CountlyFeedbackWidget.type === \"rating\") {\n url += \"/o/surveys/rating/widget\";\n }\n else {\n log(logLevelEnums.ERROR, \"getFeedbackWidgetData, Unknown type info: [\" + CountlyFeedbackWidget.type + \"]\");\n return;\n }\n\n sendXmlHttpRequest(\"getFeedbackWidgetData,\", url, data, responseCallback, true);\n\n /**\n * Server response would be evaluated here\n * @param {*} err - error object\n * @param {*} params - parameters\n * @param {*} responseText - server reponse text\n */\n function responseCallback(err, params, responseText) {\n if (err) {\n log(logLevelEnums.ERROR, \"getFeedbackWidgetData, Error occurred while fetching feedbacks: \" + err);\n if (callback) {\n callback(null, err);\n }\n return;\n }\n\n try {\n var response = JSON.parse(responseText);\n // return parsed response\n if (callback) {\n callback(response, null);\n }\n }\n catch (error) {\n log(logLevelEnums.ERROR, \"getFeedbackWidgetData, Error while parsing feedback widgets list: \" + error);\n if (callback) {\n callback(null, error);\n }\n }\n }\n };\n\n /**\n * Present the feedback widget in webview\n * @param {Object} presentableFeedback - Current presentable feedback\n * @param {String} id - DOM id to append the feedback widget\n * @param {String} className - Class name to append the feedback widget\n * */\n this.present_feedback_widget = function(presentableFeedback, id, className) {\n log(logLevelEnums.INFO, \"present_feedback_widget, Presenting the feedback widget by appending to the element with ID: [ \" + id + \" ] and className: [ \" + className + \" ]\");\n if (!this.check_consent(featureEnums.FEEDBACK)) {\n return;\n }\n\n if (!presentableFeedback\n || (typeof presentableFeedback !== \"object\")\n || Array.isArray(presentableFeedback)\n ) {\n log(logLevelEnums.ERROR, \"present_feedback_widget, Please provide at least one feedback widget object.\");\n return;\n }\n\n try {\n var url = this.url;\n\n if (presentableFeedback.type === \"nps\") {\n log(logLevelEnums.DEBUG, \"present_feedback_widget, Widget type: nps.\");\n url += \"/feedback/nps\";\n }\n else if (presentableFeedback.type === \"survey\") {\n log(logLevelEnums.DEBUG, \"present_feedback_widget, Widget type: survey.\");\n url += \"/feedback/survey\";\n }\n else if (presentableFeedback.type === \"rating\") {\n log(logLevelEnums.DEBUG, \"present_feedback_widget, Widget type: rating.\");\n url += \"/feedback/rating\";\n }\n else {\n log(logLevelEnums.ERROR, \"present_feedback_widget, Feedback widget only accepts nps, rating and survey types.\");\n return;\n }\n\n var passedOrigin = window.origin || window.location.origin;\n var feedbackWidgetFamily;\n\n // set feedback widget family as ratings and load related style file when type is ratings\n if (presentableFeedback.type === \"rating\") {\n log(logLevelEnums.DEBUG, \"present_feedback_widget, Loading css for rating widget.\");\n feedbackWidgetFamily = \"ratings\";\n loadCSS(this.url + \"/star-rating/stylesheets/countly-feedback-web.css\");\n }\n // if it's not ratings, it means we need to name it as surveys and load related style file\n // (at least until we add new type in future)\n else {\n log(logLevelEnums.DEBUG, \"present_feedback_widget, Loading css for survey or nps.\");\n loadCSS(this.url + \"/surveys/stylesheets/countly-surveys.css\");\n feedbackWidgetFamily = \"surveys\";\n }\n\n url += \"?widget_id=\" + presentableFeedback._id;\n url += \"&app_key=\" + this.app_key;\n url += \"&device_id=\" + this.device_id;\n url += \"&sdk_name=\" + SDK_NAME;\n url += \"&platform=\" + this.platform;\n url += \"&app_version=\" + this.app_version;\n url += \"&sdk_version=\" + SDK_VERSION;\n // Origin is passed to the popup so that it passes it back in the postMessage event\n // Only web SDK passes origin and web\n url += \"&origin=\" + passedOrigin;\n url += \"&widget_v=web\";\n\n var iframe = document.createElement(\"iframe\");\n iframe.src = url;\n iframe.name = \"countly-\" + feedbackWidgetFamily + \"-iframe\";\n iframe.id = \"countly-\" + feedbackWidgetFamily + \"-iframe\";\n\n var initiated = false;\n iframe.onload = function() {\n // This is used as a fallback for browsers where postMessage API doesn't work.\n\n if (initiated) {\n // On iframe reset remove the iframe and the overlay.\n document.getElementById(\"countly-\" + feedbackWidgetFamily + \"-wrapper-\" + presentableFeedback._id).style.display = \"none\";\n document.getElementById(\"csbg\").style.display = \"none\";\n }\n\n // Setting initiated marks the first time initiation of the iframe.\n // When initiated for the first time, do not hide the survey because you want\n // the survey to be shown for the first time.\n // Any subsequent onload means that the survey is being refreshed or reset.\n // This time hide it as being done in the above check.\n initiated = true;\n log(logLevelEnums.DEBUG, \"present_feedback_widget, Loaded iframe.\");\n };\n\n var overlay = document.getElementById(\"csbg\");\n while (overlay) {\n // Remove any existing overlays\n overlay.remove();\n overlay = document.getElementById(\"csbg\");\n log(logLevelEnums.DEBUG, \"present_feedback_widget, Removing past overlay.\");\n }\n\n var wrapper = document.getElementsByClassName(\"countly-\" + feedbackWidgetFamily + \"-wrapper\");\n for (var i = 0; i < wrapper.length; i++) {\n // Remove any existing feedback wrappers\n wrapper[i].remove();\n log(logLevelEnums.DEBUG, \"present_feedback_widget, Removed a wrapper.\");\n }\n\n wrapper = document.createElement(\"div\");\n wrapper.className = \"countly-\" + feedbackWidgetFamily + \"-wrapper\";\n wrapper.id = \"countly-\" + feedbackWidgetFamily + \"-wrapper-\" + presentableFeedback._id;\n\n if (presentableFeedback.type === \"survey\") {\n // Set popup position\n wrapper.className = wrapper.className + \" \" + presentableFeedback.appearance.position;\n }\n\n var element = document.body;\n var found = false;\n\n if (id) {\n if (document.getElementById(id)) {\n element = document.getElementById(id);\n found = true;\n }\n else {\n log(logLevelEnums.ERROR, \"present_feedback_widget, Provided ID not found.\");\n }\n }\n\n if (!found) {\n // If the id element is not found check if a class was provided\n if (className) {\n if (document.getElementsByClassName(className)[0]) {\n element = document.getElementsByClassName(className)[0];\n }\n else {\n log(logLevelEnums.ERROR, \"present_feedback_widget, Provided class not found.\");\n }\n }\n }\n\n element.insertAdjacentHTML(\"beforeend\", \"\");\n element.appendChild(wrapper);\n if (presentableFeedback.type === \"rating\") {\n // create a overlay div and inject it to wrapper\n var ratingsOverlay = document.createElement(\"div\");\n ratingsOverlay.className = \"countly-ratings-overlay\";\n ratingsOverlay.id = \"countly-ratings-overlay-\" + presentableFeedback._id;\n wrapper.appendChild(ratingsOverlay);\n log(logLevelEnums.DEBUG, \"present_feedback_widget, appended the rating overlay to wrapper\");\n\n // add an event listener for the overlay\n // so if someone clicked on the overlay, we can close popup\n add_event_listener(document.getElementById(\"countly-ratings-overlay-\" + presentableFeedback._id), \"click\", function() {\n document.getElementById(\"countly-ratings-wrapper-\" + presentableFeedback._id).style.display = \"none\";\n });\n }\n\n wrapper.appendChild(iframe);\n log(logLevelEnums.DEBUG, \"present_feedback_widget, Appended the iframe\");\n\n add_event_listener(window, \"message\", function(e) {\n var data = {};\n try {\n data = JSON.parse(e.data);\n log(logLevelEnums.DEBUG, \"present_feedback_widget, Parsed response message \" + data);\n }\n catch (ex) {\n log(logLevelEnums.ERROR, \"present_feedback_widget, Error while parsing message body \" + ex);\n }\n\n if (!data.close) {\n log(logLevelEnums.DEBUG, \"present_feedback_widget, Closing signal not sent yet\");\n return;\n }\n\n document.getElementById(\"countly-\" + feedbackWidgetFamily + \"-wrapper-\" + presentableFeedback._id).style.display = \"none\";\n document.getElementById(\"csbg\").style.display = \"none\";\n });\n\n if (presentableFeedback.type === \"survey\") {\n var surveyShown = false;\n\n // Set popup show policy\n switch (presentableFeedback.showPolicy) {\n case \"afterPageLoad\":\n if (document.readyState === \"complete\") {\n if (!surveyShown) {\n surveyShown = true;\n showSurvey(presentableFeedback);\n }\n }\n else {\n add_event_listener(document, \"readystatechange\", function(e) {\n if (e.target.readyState === \"complete\") {\n if (!surveyShown) {\n surveyShown = true;\n showSurvey(presentableFeedback);\n }\n }\n });\n }\n\n break;\n\n case \"afterConstantDelay\":\n setTimeout(function() {\n if (!surveyShown) {\n surveyShown = true;\n showSurvey(presentableFeedback);\n }\n }, 10000);\n\n break;\n\n case \"onAbandon\":\n if (document.readyState === \"complete\") {\n add_event_listener(document, \"mouseleave\", function() {\n if (!surveyShown) {\n surveyShown = true;\n showSurvey(presentableFeedback);\n }\n });\n }\n else {\n add_event_listener(document, \"readystatechange\", function(e) {\n if (e.target.readyState === \"complete\") {\n add_event_listener(document, \"mouseleave\", function() {\n if (!surveyShown) {\n surveyShown = true;\n showSurvey(presentableFeedback);\n }\n });\n }\n });\n }\n\n break;\n\n case \"onScrollHalfwayDown\":\n add_event_listener(window, \"scroll\", function() {\n if (!surveyShown) {\n var scrollY = Math.max(window.scrollY, document.body.scrollTop, document.documentElement.scrollTop);\n var documentHeight = getDocHeight();\n if (scrollY >= (documentHeight / 2)) {\n surveyShown = true;\n showSurvey(presentableFeedback);\n }\n }\n });\n\n break;\n\n default:\n if (!surveyShown) {\n surveyShown = true;\n showSurvey(presentableFeedback);\n }\n }\n }\n else if (presentableFeedback.type === \"nps\") {\n document.getElementById(\"countly-\" + feedbackWidgetFamily + \"-wrapper-\" + presentableFeedback._id).style.display = \"block\";\n document.getElementById(\"csbg\").style.display = \"block\";\n }\n else if (presentableFeedback.type === \"rating\") {\n var ratingShown = false;\n\n if (document.readyState === \"complete\") {\n if (!ratingShown) {\n ratingShown = true;\n showRatingForFeedbackWidget(presentableFeedback);\n }\n }\n else {\n add_event_listener(document, \"readystatechange\", function(e) {\n if (e.target.readyState === \"complete\") {\n if (!ratingShown) {\n ratingShown = true;\n showRatingForFeedbackWidget(presentableFeedback);\n }\n }\n });\n }\n }\n }\n catch (e) {\n log(logLevelEnums.ERROR, \"present_feedback_widget, Something went wrong while presenting the widget: \" + e);\n }\n\n /**\n * Function to show survey popup\n * @param {Object} feedback - feedback object\n */\n function showSurvey(feedback) {\n document.getElementById(\"countly-surveys-wrapper-\" + feedback._id).style.display = \"block\";\n document.getElementById(\"csbg\").style.display = \"block\";\n }\n\n /**\n * Function to prepare rating sticker and feedback widget\n * @param {Object} feedback - feedback object\n */\n function showRatingForFeedbackWidget(feedback) {\n // render sticker if hide sticker property isn't set\n if (!feedback.appearance.hideS) {\n log(logLevelEnums.DEBUG, \"present_feedback_widget, handling the sticker as it was not set to hidden\");\n // create sticker wrapper element\n var sticker = document.createElement(\"div\");\n sticker.innerText = feedback.appearance.text;\n sticker.style.color = ((feedback.appearance.text_color.length < 7) ? \"#\" + feedback.appearance.text_color : feedback.appearance.text_color);\n sticker.style.backgroundColor = ((feedback.appearance.bg_color.length < 7) ? \"#\" + feedback.appearance.bg_color : feedback.appearance.bg_color);\n sticker.className = \"countly-feedback-sticker \" + feedback.appearance.position + \"-\" + feedback.appearance.size;\n sticker.id = \"countly-feedback-sticker-\" + feedback._id;\n document.body.appendChild(sticker);\n\n // sticker event handler\n add_event_listener(document.getElementById(\"countly-feedback-sticker-\" + feedback._id), \"click\", function() {\n document.getElementById(\"countly-ratings-wrapper-\" + feedback._id).style.display = \"flex\";\n document.getElementById(\"csbg\").style.display = \"block\";\n });\n }\n\n // feedback widget close event handler\n // TODO: Check if this is still valid\n add_event_listener(document.getElementById(\"countly-feedback-close-icon-\" + feedback._id), \"click\", function() {\n document.getElementById(\"countly-ratings-wrapper-\" + feedback._id).style.display = \"none\";\n document.getElementById(\"csbg\").style.display = \"none\";\n });\n }\n };\n\n /**\n * Record and report error, this is were tracked errors are modified and send to the request queue\n * @param {Error} err - Error object\n * @param {Boolean} nonfatal - nonfatal if true and false if fatal\n * @param {Object} segments - custom crash segments\n */\n this.recordError = function(err, nonfatal, segments) {\n log(logLevelEnums.INFO, \"recordError, Recording error\");\n if (this.check_consent(featureEnums.CRASHES) && err) {\n // crashSegments, if not null, was set while enabling error tracking\n segments = segments || crashSegments;\n var error = \"\";\n if (typeof err === \"object\") {\n if (typeof err.stack !== \"undefined\") {\n error = err.stack;\n }\n else {\n if (typeof err.name !== \"undefined\") {\n error += err.name + \":\";\n }\n if (typeof err.message !== \"undefined\") {\n error += err.message + \"\\n\";\n }\n if (typeof err.fileName !== \"undefined\") {\n error += \"in \" + err.fileName + \"\\n\";\n }\n if (typeof err.lineNumber !== \"undefined\") {\n error += \"on \" + err.lineNumber;\n }\n if (typeof err.columnNumber !== \"undefined\") {\n error += \":\" + err.columnNumber;\n }\n }\n }\n else {\n error = err + \"\";\n }\n // character limit check\n if (error.length > (self.maxStackTraceLineLength * self.maxStackTraceLinesPerThread)) {\n log(logLevelEnums.DEBUG, \"record_error, Error stack is too long will be truncated\");\n // convert error into an array split from each newline \n var splittedError = error.split(\"\\n\");\n // trim the array if it is too long\n if (splittedError.length > self.maxStackTraceLinesPerThread) {\n splittedError = splittedError.splice(0, self.maxStackTraceLinesPerThread);\n }\n // trim each line to a given limit\n for (var i = 0, len = splittedError.length; i < len; i++) {\n if (splittedError[i].length > self.maxStackTraceLineLength) {\n splittedError[i] = splittedError[i].substring(0, self.maxStackTraceLineLength);\n }\n }\n // turn modified array back into error string\n error = splittedError.join(\"\\n\");\n }\n\n nonfatal = !!(nonfatal);\n var metrics = getMetrics();\n var obj = { _resolution: metrics._resolution, _error: error, _app_version: metrics._app_version, _run: getTimestamp() - startTime };\n\n obj._not_os_specific = true;\n obj._javascript = true;\n\n var battery = navigator.battery || navigator.webkitBattery || navigator.mozBattery || navigator.msBattery;\n if (battery) {\n obj._bat = Math.floor(battery.level * 100);\n }\n\n if (typeof navigator.onLine !== \"undefined\") {\n obj._online = !!(navigator.onLine);\n }\n\n obj._background = !(document.hasFocus());\n\n if (crashLogs.length > 0) {\n obj._logs = crashLogs.join(\"\\n\");\n }\n crashLogs = [];\n\n obj._nonfatal = nonfatal;\n\n obj._view = this.getViewName();\n\n if (typeof segments !== \"undefined\") {\n // truncate custom crash segment's key value pairs\n segments = truncateObject(segments, self.maxKeyLength, self.maxValueSize, self.maxSegmentationValues, \"record_error\", log);\n obj._custom = segments;\n }\n\n try {\n var canvas = document.createElement(\"canvas\");\n var gl = canvas.getContext(\"experimental-webgl\");\n obj._opengl = gl.getParameter(gl.VERSION);\n }\n catch (ex) {\n log(logLevelEnums.ERROR, \"Could not get the experimental-webgl context: \" + ex);\n }\n\n // send userAgent string with the crash object incase it gets removed by a gateway\n var req = {};\n req.crash = JSON.stringify(obj);\n req.metrics = JSON.stringify({ _ua: metrics._ua });\n\n toRequestQueue(req);\n }\n };\n\n /**\n * Check if user or visit should be ignored\n */\n function checkIgnore() {\n if (self.ignore_prefetch && typeof document.visibilityState !== \"undefined\" && document.visibilityState === \"prerender\") {\n self.ignore_visitor = true;\n }\n if (self.ignore_bots && userAgentSearchBotDetection()) {\n self.ignore_visitor = true;\n }\n }\n\n /**\n * Check and send the events to request queue if there are any, empty the event queue\n */\n function sendEventsForced() {\n if (eventQueue.length > 0) {\n log(logLevelEnums.DEBUG, \"Flushing events\");\n toRequestQueue({ events: JSON.stringify(eventQueue) });\n eventQueue = [];\n setValueInStorage(\"cly_event\", eventQueue);\n }\n }\n\n /**\n * Prepare widget data for displaying\n * @param {Object} currentWidget - widget object\n * @param {Boolean} hasSticker - if widget has sticker\n */\n function processWidget(currentWidget, hasSticker) {\n // prevent widget create process if widget exist with same id\n var isDuplicate = !!document.getElementById(\"countly-feedback-sticker-\" + currentWidget._id);\n if (isDuplicate) {\n log(logLevelEnums.ERROR, \"Widget with same ID exists\");\n return;\n }\n try {\n // create wrapper div\n var wrapper = document.createElement(\"div\");\n wrapper.className = \"countly-iframe-wrapper\";\n wrapper.id = \"countly-iframe-wrapper-\" + currentWidget._id;\n // create close icon for iframe popup\n var closeIcon = document.createElement(\"span\");\n closeIcon.className = \"countly-feedback-close-icon\";\n closeIcon.id = \"countly-feedback-close-icon-\" + currentWidget._id;\n closeIcon.innerText = \"x\";\n\n // create iframe\n var iframe = document.createElement(\"iframe\");\n iframe.name = \"countly-feedback-iframe\";\n iframe.id = \"countly-feedback-iframe\";\n iframe.src = self.url + \"/feedback?widget_id=\" + currentWidget._id + \"&app_key=\" + self.app_key + \"&device_id=\" + self.device_id + \"&sdk_version=\" + SDK_VERSION;\n // inject them to dom\n document.body.appendChild(wrapper);\n wrapper.appendChild(closeIcon);\n wrapper.appendChild(iframe);\n add_event_listener(document.getElementById(\"countly-feedback-close-icon-\" + currentWidget._id), \"click\", function() {\n document.getElementById(\"countly-iframe-wrapper-\" + currentWidget._id).style.display = \"none\";\n document.getElementById(\"cfbg\").style.display = \"none\";\n });\n if (hasSticker) {\n // create svg element\n var svgIcon = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\");\n svgIcon.id = \"feedback-sticker-svg\";\n svgIcon.setAttribute(\"aria-hidden\", \"true\");\n svgIcon.setAttribute(\"data-prefix\", \"far\");\n svgIcon.setAttribute(\"data-icon\", \"grin\");\n svgIcon.setAttribute(\"class\", \"svg-inline--fa fa-grin fa-w-16\");\n svgIcon.setAttribute(\"role\", \"img\");\n svgIcon.setAttribute(\"xmlns\", \"http://www.w3.org/2000/svg\");\n svgIcon.setAttribute(\"viewBox\", \"0 0 496 512\");\n // create path for svg\n var svgPath = document.createElementNS(\"http://www.w3.org/2000/svg\", \"path\");\n svgPath.id = \"smileyPathInStickerSvg\";\n svgPath.setAttribute(\"fill\", \"white\");\n svgPath.setAttribute(\"d\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 448c-110.3 0-200-89.7-200-200S137.7 56 248 56s200 89.7 200 200-89.7 200-200 200zm105.6-151.4c-25.9 8.3-64.4 13.1-105.6 13.1s-79.6-4.8-105.6-13.1c-9.9-3.1-19.4 5.4-17.7 15.3 7.9 47.1 71.3 80 123.3 80s115.3-32.9 123.3-80c1.6-9.8-7.7-18.4-17.7-15.3zM168 240c17.7 0 32-14.3 32-32s-14.3-32-32-32-32 14.3-32 32 14.3 32 32 32zm160 0c17.7 0 32-14.3 32-32s-14.3-32-32-32-32 14.3-32 32 14.3 32 32 32z\");\n // create sticker text wrapper\n var stickerText = document.createElement(\"span\");\n stickerText.innerText = currentWidget.trigger_button_text;\n // create sticker wrapper element\n var sticker = document.createElement(\"div\");\n sticker.style.color = ((currentWidget.trigger_font_color.length < 7) ? \"#\" + currentWidget.trigger_font_color : currentWidget.trigger_font_color);\n sticker.style.backgroundColor = ((currentWidget.trigger_bg_color.length < 7) ? \"#\" + currentWidget.trigger_bg_color : currentWidget.trigger_bg_color);\n sticker.className = \"countly-feedback-sticker \" + currentWidget.trigger_position + \"-\" + currentWidget.trigger_size;\n sticker.id = \"countly-feedback-sticker-\" + currentWidget._id;\n svgIcon.appendChild(svgPath);\n sticker.appendChild(svgIcon);\n sticker.appendChild(stickerText);\n document.body.appendChild(sticker);\n var smileySvg = document.getElementById(\"smileyPathInStickerSvg\");\n if (smileySvg) {\n smileySvg.style.fill = ((currentWidget.trigger_font_color.length < 7) ? \"#\" + currentWidget.trigger_font_color : currentWidget.trigger_font_color);\n }\n add_event_listener(document.getElementById(\"countly-feedback-sticker-\" + currentWidget._id), \"click\", function() {\n document.getElementById(\"countly-iframe-wrapper-\" + currentWidget._id).style.display = \"block\";\n document.getElementById(\"cfbg\").style.display = \"block\";\n });\n }\n else {\n document.getElementById(\"countly-iframe-wrapper-\" + currentWidget._id).style.display = \"block\";\n document.getElementById(\"cfbg\").style.display = \"block\";\n }\n }\n catch (e) {\n log(logLevelEnums.ERROR, \"Somethings went wrong while element injecting process: \" + e);\n }\n }\n\n /**\n * Notify all waiting callbacks that script was loaded and instance created\n */\n function notifyLoaders() {\n // notify load waiters\n var i;\n if (typeof self.onload !== \"undefined\" && self.onload.length > 0) {\n for (i = 0; i < self.onload.length; i++) {\n if (typeof self.onload[i] === \"function\") {\n self.onload[i](self);\n }\n }\n self.onload = [];\n }\n }\n\n /**\n * Report duration of how long user was on this view\n * @memberof Countly._internals\n */\n function reportViewDuration() {\n if (lastView) {\n var segments = {\n name: lastView\n };\n\n // track pageview\n if (self.check_consent(featureEnums.VIEWS)) {\n add_cly_events({\n key: internalEventKeyEnums.VIEW,\n dur: (trackTime) ? getTimestamp() - lastViewTime : lastViewStoredDuration,\n segmentation: segments\n }, currentViewId);\n lastView = null;\n }\n }\n }\n\n /**\n * Get last view that user visited\n * @memberof Countly._internals\n * @returns {String} view name\n */\n function getLastView() {\n return lastView;\n }\n\n /**\n * Extend session's cookie's time\n */\n function extendSession() {\n if (useSessionCookie) {\n // if session expired, we should start a new one\n var expire = getValueFromStorage(\"cly_session\");\n if (!expire || parseInt(expire) <= getTimestamp()) {\n sessionStarted = false;\n self.begin_session(!autoExtend);\n }\n setValueInStorage(\"cly_session\", getTimestamp() + (sessionCookieTimeout * 60));\n }\n }\n\n /**\n * Prepare request params by adding common properties to it\n * @param {Object} request - request object\n */\n function prepareRequest(request) {\n request.app_key = self.app_key;\n request.device_id = self.device_id;\n request.sdk_name = SDK_NAME;\n request.sdk_version = SDK_VERSION;\n request.t = deviceIdType;\n request.av = self.app_version;\n\n var ua = getUA();\n if (!request.metrics) { // if metrics not provided pass useragent with this event\n request.metrics = JSON.stringify({ _ua: ua });\n }\n else { // if metrics provided\n var currentMetrics = JSON.parse(request.metrics);\n if (!currentMetrics._ua) { // check if ua is present and if not add that\n currentMetrics._ua = ua;\n request.metrics = JSON.stringify(currentMetrics);\n }\n }\n\n if (self.check_consent(featureEnums.LOCATION)) {\n if (self.country_code) {\n request.country_code = self.country_code;\n }\n\n if (self.city) {\n request.city = self.city;\n }\n\n if (self.ip_address !== null) {\n request.ip_address = self.ip_address;\n }\n }\n else {\n request.location = \"\";\n }\n\n request.timestamp = getMsTimestamp();\n\n var date = new Date();\n request.hour = date.getHours();\n request.dow = date.getDay();\n }\n\n /**\n * Add request to request queue\n * @memberof Countly._internals\n * @param {Object} request - object with request parameters\n */\n function toRequestQueue(request) {\n if (self.ignore_visitor) {\n log(logLevelEnums.WARNING, \"User is opt_out will ignore the request: \" + request);\n return;\n }\n\n if (!self.app_key || !self.device_id) {\n log(logLevelEnums.ERROR, \"app_key or device_id is missing \", self.app_key, self.device_id);\n return;\n }\n\n prepareRequest(request);\n\n if (requestQueue.length > queueSize) {\n requestQueue.shift();\n }\n\n requestQueue.push(request);\n setValueInStorage(\"cly_queue\", requestQueue, true);\n }\n\n /**\n * Making request making and data processing loop\n * @memberof Countly._internals\n * @returns {void} void\n */\n function heartBeat() {\n notifyLoaders();\n\n // ignore bots\n if (self.ignore_visitor) {\n hasPulse = false;\n log(logLevelEnums.WARNING, \"User opt_out, no heartbeat\");\n return;\n }\n\n hasPulse = true;\n var i = 0;\n // process queue\n if (global && typeof Countly.q !== \"undefined\" && Countly.q.length > 0) {\n var req;\n var q = Countly.q;\n Countly.q = [];\n for (i = 0; i < q.length; i++) {\n req = q[i];\n log(logLevelEnums.DEBUG, \"Processing queued call\", req);\n if (typeof req === \"function\") {\n req();\n }\n else if (Array.isArray(req) && req.length > 0) {\n var inst = self;\n var arg = 0;\n // check if it is meant for other tracker\n if (Countly.i[req[arg]]) {\n inst = Countly.i[req[arg]];\n arg++;\n }\n if (typeof inst[req[arg]] === \"function\") {\n inst[req[arg]].apply(inst, req.slice(arg + 1));\n }\n else if (req[arg].indexOf(\"userData.\") === 0) {\n var userdata = req[arg].replace(\"userData.\", \"\");\n if (typeof inst.userData[userdata] === \"function\") {\n inst.userData[userdata].apply(inst, req.slice(arg + 1));\n }\n }\n else if (typeof Countly[req[arg]] === \"function\") {\n Countly[req[arg]].apply(Countly, req.slice(arg + 1));\n }\n }\n }\n }\n\n // extend session if needed\n if (sessionStarted && autoExtend && trackTime) {\n var last = getTimestamp();\n if (last - lastBeat > sessionUpdate) {\n self.session_duration(last - lastBeat);\n lastBeat = last;\n // save health check logging counters if there are any\n if (self.hcErrorCount > 0) {\n setValueInStorage(healthCheckCounterEnum.errorCount, self.hcErrorCount);\n }\n if (self.hcWarningCount > 0) {\n setValueInStorage(healthCheckCounterEnum.warningCount, self.hcWarningCount);\n }\n }\n }\n\n // process event queue\n if (eventQueue.length > 0 && !self.test_mode_eq) {\n if (eventQueue.length <= maxEventBatch) {\n toRequestQueue({ events: JSON.stringify(eventQueue) });\n eventQueue = [];\n }\n else {\n var events = eventQueue.splice(0, maxEventBatch);\n toRequestQueue({ events: JSON.stringify(events) });\n }\n setValueInStorage(\"cly_event\", eventQueue);\n }\n\n // process request queue with event queue\n if (!offlineMode && requestQueue.length > 0 && readyToProcess && getTimestamp() > failTimeout) {\n readyToProcess = false;\n var params = requestQueue[0];\n params.rr = requestQueue.length; // added at 23.2.3. It would give the current length of the queue. That includes the current request.\n log(logLevelEnums.DEBUG, \"Processing request\", params);\n setValueInStorage(\"cly_queue\", requestQueue, true);\n if (!self.test_mode) {\n sendXmlHttpRequest(\"send_request_queue\", self.url + apiPath, params, function(err, parameters) {\n log(logLevelEnums.DEBUG, \"Request Finished\", parameters, err);\n if (err) {\n failTimeout = getTimestamp() + failTimeoutAmount;\n log(logLevelEnums.ERROR, \"Request error: \", err);\n }\n else {\n // remove first item from queue\n requestQueue.shift();\n }\n setValueInStorage(\"cly_queue\", requestQueue, true);\n readyToProcess = true;\n // expected response is only JSON object\n }, false);\n }\n }\n\n setTimeout(heartBeat, beatInterval);\n }\n\n /**\n * Get device ID, stored one, or generate new one\n * @memberof Countly._internals\n * @returns {String} device id\n */\n function getStoredIdOrGenerateId() {\n var storedDeviceId = getValueFromStorage(\"cly_id\");\n if (storedDeviceId) {\n deviceIdType = getValueFromStorage(\"cly_id_type\");\n return storedDeviceId;\n }\n return generateUUID();\n }\n\n /**\n * Check if value is in UUID format\n * @memberof Countly._internals\n * @param {string} providedId - Id to check\n * @returns {Boolean} true if it is in UUID format\n */\n function isUUID(providedId) {\n return /[0-9a-fA-F]{8}\\-[0-9a-fA-F]{4}\\-4[0-9a-fA-F]{3}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{12}/.test(providedId);\n }\n\n /**\n * Get and return user agentAgent\n * @memberof Countly._internals\n * @returns {string} returns userAgent string\n */\n function getUA() {\n return self.metrics._ua || currentUserAgentString();\n }\n\n /**\n * Get metrics of the browser or config object\n * @memberof Countly._internals\n * @returns {Object} Metrics object\n */\n function getMetrics() {\n var metrics = JSON.parse(JSON.stringify(self.metrics || {}));\n\n // getting app version\n metrics._app_version = metrics._app_version || self.app_version;\n metrics._ua = metrics._ua || currentUserAgentString();\n\n // getting resolution\n if (screen.width) {\n var width = (screen.width) ? parseInt(screen.width) : 0;\n var height = (screen.height) ? parseInt(screen.height) : 0;\n if (width !== 0 && height !== 0) {\n var iOS = !!navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform);\n if (iOS && window.devicePixelRatio) {\n // ios provides dips, need to multiply\n width = Math.round(width * window.devicePixelRatio);\n height = Math.round(height * window.devicePixelRatio);\n }\n else {\n if (Math.abs(window.orientation) === 90) {\n // we have landscape orientation\n // switch values for all except ios\n var temp = width;\n width = height;\n height = temp;\n }\n }\n metrics._resolution = metrics._resolution || \"\" + width + \"x\" + height;\n }\n }\n\n // getting density ratio\n if (window.devicePixelRatio) {\n metrics._density = metrics._density || window.devicePixelRatio;\n }\n\n // getting locale\n var locale = navigator.language || navigator.browserLanguage || navigator.systemLanguage || navigator.userLanguage;\n if (typeof locale !== \"undefined\") {\n metrics._locale = metrics._locale || locale;\n }\n\n if (isReferrerUsable()) {\n metrics._store = metrics._store || document.referrer;\n }\n\n log(logLevelEnums.DEBUG, \"Got metrics\", metrics);\n return metrics;\n }\n\n /**\n * @memberof Countly._internals\n * document.referrer returns the full URL of the page the user was on before they came to your site.\n * If the user open your site from bookmarks or by typing the URL in the address bar, then document.referrer is an empty string.\n * Inside an iframe, document.referrer will initially be set to the same value as the href of the parent window's Window.location. \n * \n * @param {string} customReferrer - custom referrer for testing\n * @returns {boolean} true if document.referrer is not empty string, undefined, current host or in the ignore list.\n */\n function isReferrerUsable(customReferrer) {\n var referrer = customReferrer || document.referrer;\n var isReferrerLegit = false;\n\n // do not report referrer if it is empty string or undefined\n if (typeof referrer === \"undefined\" || referrer.length === 0) {\n log(logLevelEnums.DEBUG, \"Invalid referrer:[\" + referrer + \"], ignoring.\");\n }\n else {\n // dissect the referrer (check urlParseRE's comments for more info on this process)\n var matches = urlParseRE.exec(referrer); // this can return null\n if (!matches) {\n log(logLevelEnums.DEBUG, \"Referrer is corrupt:[\" + referrer + \"], ignoring.\");\n }\n else if (!matches[11]) {\n log(logLevelEnums.DEBUG, \"No path found in referrer:[\" + referrer + \"], ignoring.\");\n }\n else if (matches[11] === window.location.hostname) {\n log(logLevelEnums.DEBUG, \"Referrer is current host:[\" + referrer + \"], ignoring.\");\n }\n else {\n if (ignoreReferrers && ignoreReferrers.length) {\n isReferrerLegit = true;\n for (var k = 0; k < ignoreReferrers.length; k++) {\n if (referrer.indexOf(ignoreReferrers[k]) >= 0) {\n log(logLevelEnums.DEBUG, \"Referrer in ignore list:[\" + referrer + \"], ignoring.\");\n isReferrerLegit = false;\n break;\n }\n }\n }\n else {\n log(logLevelEnums.DEBUG, \"Valid referrer:[\" + referrer + \"]\");\n isReferrerLegit = true;\n }\n }\n }\n\n return isReferrerLegit;\n }\n\n /**\n * Logging stuff, works only when debug mode is true\n * @param {string} level - log level (error, warning, info, debug, verbose)\n * @param {string} message - any string message\n * @memberof Countly._internals\n */\n function log(level, message) {\n if (self.debug && typeof console !== \"undefined\") {\n // parse the arguments into a string if it is an object\n if (arguments[2] && typeof arguments[2] === \"object\") {\n arguments[2] = JSON.stringify(arguments[2]);\n }\n // append app_key to the start of the message if it is not the first instance (for multi instancing)\n if (!global) {\n message = \"[\" + self.app_key + \"] \" + message;\n }\n // if the provided level is not a proper log level re-assign it as [DEBUG]\n if (!level) {\n level = logLevelEnums.DEBUG;\n }\n // append level, message and args\n var extraArguments = \"\";\n for (var i = 2; i < arguments.length; i++) {\n extraArguments += arguments[i];\n }\n // eslint-disable-next-line no-shadow\n var log = level + \"[Countly] \" + message + extraArguments;\n // decide on the console\n if (level === logLevelEnums.ERROR) {\n // eslint-disable-next-line no-console\n console.error(log);\n HealthCheck.incrementErrorCount();\n }\n else if (level === logLevelEnums.WARNING) {\n // eslint-disable-next-line no-console\n console.warn(log);\n HealthCheck.incrementWarningCount();\n }\n else if (level === logLevelEnums.INFO) {\n // eslint-disable-next-line no-console\n console.info(log);\n }\n else if (level === logLevelEnums.VERBOSE) {\n // eslint-disable-next-line no-console\n console.log(log);\n }\n // if none of the above must be [DEBUG]\n else {\n // eslint-disable-next-line no-console\n console.debug(log);\n }\n }\n }\n\n /**\n * Making xml HTTP request\n * @memberof Countly._internals\n * @param {String} functionName - Name of the function making the request for more detailed logging\n * @param {String} url - URL where to make request\n * @param {Object} params - key value object with URL params\n * @param {Function} callback - callback when request finished or failed\n * @param {Boolean} useBroadResponseValidator - if true that means the expected response is either a JSON object or a JSON array, if false only JSON \n */\n function sendXmlHttpRequest(functionName, url, params, callback, useBroadResponseValidator) {\n useBroadResponseValidator = useBroadResponseValidator || false;\n try {\n log(logLevelEnums.DEBUG, \"Sending XML HTTP request\");\n var xhr = null;\n if (window.XMLHttpRequest) {\n xhr = new window.XMLHttpRequest();\n }\n else if (window.ActiveXObject) {\n xhr = new window.ActiveXObject(\"Microsoft.XMLHTTP\");\n }\n params = params || {};\n var data = prepareParams(params);\n var method = \"GET\";\n if (self.force_post || data.length >= 2000) {\n method = \"POST\";\n }\n if (method === \"GET\") {\n xhr.open(\"GET\", url + \"?\" + data, true);\n }\n else {\n xhr.open(\"POST\", url, true);\n xhr.setRequestHeader(\"Content-type\", \"application/x-www-form-urlencoded\");\n }\n for (var header in self.headers) {\n xhr.setRequestHeader(header, self.headers[header]);\n }\n // fallback on error\n xhr.onreadystatechange = function() {\n if (this.readyState === 4) {\n log(logLevelEnums.DEBUG, functionName + \" HTTP request completed [\" + this.status + \"][\" + this.responseText + \"]\");\n // response validation function will be selected to also accept JSON arrays if useBroadResponseValidator is true\n var isResponseValidated;\n if (useBroadResponseValidator) {\n // JSON array/object both can pass\n isResponseValidated = isResponseValidBroad(this.status, this.responseText);\n }\n else {\n // only JSON object can pass\n isResponseValidated = isResponseValid(this.status, this.responseText);\n }\n if (isResponseValidated) {\n if (typeof callback === \"function\") {\n callback(false, params, this.responseText);\n }\n }\n else {\n log(logLevelEnums.ERROR, functionName + \" Failed Server XML HTTP request, \", this.status);\n if (functionName === \"send_request_queue\") {\n HealthCheck.saveRequestCounters(this.status, this.responseText);\n }\n if (typeof callback === \"function\") {\n callback(true, params, this.status, this.responseText);\n }\n }\n }\n };\n if (method === \"GET\") {\n xhr.send();\n }\n else {\n xhr.send(data);\n }\n }\n catch (e) {\n // fallback\n log(logLevelEnums.ERROR, functionName + \" Failed XML HTTP request: \" + e);\n if (typeof callback === \"function\") {\n callback(true, params);\n }\n }\n }\n\n /**\n * Check if the http response fits the bill of:\n * 1. The HTTP response code was successful (which is any 2xx code or code between 200 <= x < 300)\n * 2. The returned request is a JSON object\n * @memberof Countly._internals\n * @param {Number} statusCode - http incoming statusCode.\n * @param {String} str - response from server, ideally must be: {\"result\":\"Success\"} or should contain at least result field\n * @returns {Boolean} - returns true if response passes the tests \n */\n function isResponseValid(statusCode, str) {\n // status code and response format check\n if (!(statusCode >= 200 && statusCode < 300)) {\n log(logLevelEnums.ERROR, \"Http response status code is not within the expected range:[\" + statusCode + \"]\");\n return false;\n }\n\n // Try to parse JSON\n try {\n var parsedResponse = JSON.parse(str);\n\n // check if parsed response is a JSON object, if not the response is not valid\n if (Object.prototype.toString.call(parsedResponse) !== \"[object Object]\") {\n log(logLevelEnums.ERROR, \"Http response is not JSON Object\");\n return false;\n }\n\n return !!(parsedResponse.result);\n }\n catch (e) {\n log(logLevelEnums.ERROR, \"Http response is not JSON: \" + e);\n return false;\n }\n }\n\n /**\n * Check if the http response fits the bill of:\n * 1. The HTTP response code was successful (which is any 2xx code or code between 200 <= x < 300)\n * 2. The returned request is a JSON object or JSON Array\n * @memberof Countly._internals\n * @param {Number} statusCode - http incoming statusCode.\n * @param {String} str - response from server, ideally must be: {\"result\":\"Success\"} or should contain at least result field\n * @returns {Boolean} - returns true if response passes the tests \n */\n function isResponseValidBroad(statusCode, str) {\n // status code and response format check\n if (!(statusCode >= 200 && statusCode < 300)) {\n log(logLevelEnums.ERROR, \"Http response status code is not within the expected range: \" + statusCode);\n return false;\n }\n\n // Try to parse JSON\n try {\n var parsedResponse = JSON.parse(str);\n // check if parsed response is a JSON object or JSON array, if not it is not valid \n if ((Object.prototype.toString.call(parsedResponse) !== \"[object Object]\") && (!Array.isArray(parsedResponse))) {\n log(logLevelEnums.ERROR, \"Http response is not JSON Object nor JSON Array\");\n return false;\n }\n\n // request should be accepted even if does not have result field\n return true;\n }\n catch (e) {\n log(logLevelEnums.ERROR, \"Http response is not JSON: \" + e);\n return false;\n }\n }\n\n /**\n * Get max scroll position\n * @memberof Countly._internals\n * \n */\n function processScroll() {\n scrollRegistryTopPosition = Math.max(scrollRegistryTopPosition, window.scrollY, document.body.scrollTop, document.documentElement.scrollTop);\n }\n\n /**\n * Process scroll data\n * @memberof Countly._internals\n */\n function processScrollView() {\n if (isScrollRegistryOpen) {\n isScrollRegistryOpen = false;\n var height = getDocHeight();\n var width = getDocWidth();\n\n var viewportHeight = getViewportHeight();\n\n if (self.check_consent(featureEnums.SCROLLS)) {\n var segments = {\n type: \"scroll\",\n y: scrollRegistryTopPosition + viewportHeight,\n width: width,\n height: height,\n view: self.getViewUrl()\n };\n // truncate new segment\n segments = truncateObject(segments, self.maxKeyLength, self.maxValueSize, self.maxSegmentationValues, \"processScrollView\", log);\n if (self.track_domains) {\n segments.domain = window.location.hostname;\n }\n add_cly_events({\n key: internalEventKeyEnums.ACTION,\n segmentation: segments\n });\n }\n }\n }\n\n /**\n * Fetches the current device Id type\n * @memberof Countly._internals\n * @returns {String} token - auth token\n */\n function getInternalDeviceIdType() {\n return deviceIdType;\n }\n\n /**\n * Set auth token\n * @memberof Countly._internals\n * @param {String} token - auth token\n */\n function setToken(token) {\n setValueInStorage(\"cly_token\", token);\n }\n\n /**\n * Get auth token\n * @memberof Countly._internals\n * @returns {String} auth token\n */\n function getToken() {\n var token = getValueFromStorage(\"cly_token\");\n removeValueFromStorage(\"cly_token\");\n return token;\n }\n\n /**\n * Get event queue\n * @memberof Countly._internals\n * @returns {Array} event queue\n */\n function getEventQueue() {\n return eventQueue;\n }\n\n /**\n * Get request queue\n * @memberof Countly._internals\n * @returns {Array} request queue\n */\n function getRequestQueue() {\n return requestQueue;\n }\n\n /**\n * Returns contents of a cookie\n * @param {String} cookieKey - The key, name or identifier for the cookie\n * @returns {Varies} stored value\n */\n function readCookie(cookieKey) {\n var cookieID = cookieKey + \"=\";\n // array of all cookies available\n var cookieArray = document.cookie.split(\";\");\n for (var i = 0, max = cookieArray.length; i < max; i++) {\n // cookie from the cookie array to be checked\n var cookie = cookieArray[i];\n // get rid of empty spaces at the beginning\n while (cookie.charAt(0) === \" \") {\n cookie = cookie.substring(1, cookie.length);\n }\n // return the cookie if it is the one we are looking for\n if (cookie.indexOf(cookieID) === 0) {\n // just return the value part after '='\n return cookie.substring(cookieID.length, cookie.length);\n }\n }\n return null;\n }\n\n /**\n * Creates new cookie or removes cookie with negative expiration\n * @param {String} cookieKey - The key or identifier for the storage\n * @param {String} cookieVal - Contents to store\n * @param {Number} exp - Expiration in days\n */\n function createCookie(cookieKey, cookieVal, exp) {\n var date = new Date();\n date.setTime(date.getTime() + (exp * 24 * 60 * 60 * 1000));\n // TODO: If we offer the developer the ability to manipulate the expiration date in the future, this part must be reworked\n var expires = \"; expires=\" + date.toGMTString();\n document.cookie = cookieKey + \"=\" + cookieVal + expires + \"; path=/\";\n }\n\n /**\n * Storage function that acts as getter, can be used for fetching data from local storage or cookies\n * @memberof Countly._internals\n * @param {String} key - storage key\n * @param {Boolean} useLocalStorage - if false, will fallback to cookie storage\n * @param {Boolean} useRawKey - if true, raw key will be used without any prefix\n * @returns {Varies} values stored for key\n */\n function getValueFromStorage(key, useLocalStorage, useRawKey) {\n // check if we should use storage at all\n if (self.storage === \"none\") {\n log(logLevelEnums.WARNING, \"Storage is disabled. Value with key: \" + key + \" won't be retrieved\");\n return;\n }\n\n // apply namespace or app_key\n if (!useRawKey) {\n key = self.app_key + \"/\" + key;\n if (self.namespace) {\n key = stripTrailingSlash(self.namespace) + \"/\" + key;\n }\n }\n\n // developer set values takes priority\n if (useLocalStorage === undefined) {\n useLocalStorage = lsSupport;\n }\n var data;\n\n // Get value\n if (useLocalStorage) { // Native support\n data = localStorage.getItem(key);\n }\n else if (self.storage !== \"localstorage\") { // Use cookie\n data = readCookie(key);\n }\n\n // we return early without parsing if we are trying to get the device ID. This way we are keeping it as a string incase it was numerical.\n if (key.endsWith(\"cly_id\")) {\n return data;\n }\n\n return self.deserialize(data);\n }\n\n /**\n * Storage function that acts as setter, can be used for setting data into local storage or as cookies\n * @memberof Countly._internals\n * @param {String} key - storage key\n * @param {Varies} value - value to set for key\n * @param {Boolean} useLocalStorage - if false, will fallback to storing as cookies\n * @param {Boolean} useRawKey - if true, raw key will be used without any prefix\n */\n function setValueInStorage(key, value, useLocalStorage, useRawKey) {\n // check if we should use storage options at all\n if (self.storage === \"none\") {\n log(logLevelEnums.WARNING, \"Storage is disabled. Value with key: \" + key + \" won't be stored\");\n return;\n }\n\n // apply namespace\n if (!useRawKey) {\n key = self.app_key + \"/\" + key;\n if (self.namespace) {\n key = stripTrailingSlash(self.namespace) + \"/\" + key;\n }\n }\n\n // developer set values takes priority\n if (useLocalStorage === undefined) {\n useLocalStorage = lsSupport;\n }\n\n if (typeof value !== \"undefined\" && value !== null) {\n value = self.serialize(value);\n // Set the store\n if (useLocalStorage) { // Native support\n localStorage.setItem(key, value);\n }\n else if (self.storage !== \"localstorage\") { // Use Cookie\n createCookie(key, value, 30);\n }\n }\n }\n\n /**\n * A function that can be used for removing data from local storage or cookies\n * @memberof Countly._internals\n * @param {String} key - storage key\n * @param {Boolean} useLocalStorage - if false, will fallback to removing cookies\n * @param {Boolean} useRawKey - if true, raw key will be used without any prefix\n */\n function removeValueFromStorage(key, useLocalStorage, useRawKey) {\n // check if we should use storage options at all\n if (self.storage === \"none\") {\n log(logLevelEnums.WARNING, \"Storage is disabled. Value with key: \" + key + \" won't be removed\");\n return;\n }\n\n // apply namespace\n if (!useRawKey) {\n key = self.app_key + \"/\" + key;\n if (self.namespace) {\n key = stripTrailingSlash(self.namespace) + \"/\" + key;\n }\n }\n\n // developer set values takes priority\n if (useLocalStorage === undefined) {\n useLocalStorage = lsSupport;\n }\n\n if (useLocalStorage) { // Native support\n localStorage.removeItem(key);\n }\n else if (self.storage !== \"localstorage\") { // Use cookie\n createCookie(key, \"\", -1);\n }\n }\n\n /**\n * Migrate from old storage to new app_key prefixed storage\n */\n function migrate() {\n if (getValueFromStorage(self.namespace + \"cly_id\", false, true)) {\n // old data exists, we should migrate it\n setValueInStorage(\"cly_id\", getValueFromStorage(self.namespace + \"cly_id\", false, true));\n setValueInStorage(\"cly_id_type\", getValueFromStorage(self.namespace + \"cly_id_type\", false, true));\n setValueInStorage(\"cly_event\", getValueFromStorage(self.namespace + \"cly_event\", false, true));\n setValueInStorage(\"cly_session\", getValueFromStorage(self.namespace + \"cly_session\", false, true));\n\n // filter out requests with correct app_key\n var requests = getValueFromStorage(self.namespace + \"cly_queue\", false, true);\n if (Array.isArray(requests)) {\n requests = requests.filter(function(req) {\n return req.app_key === self.app_key;\n });\n setValueInStorage(\"cly_queue\", requests);\n }\n if (getValueFromStorage(self.namespace + \"cly_cmp_id\", false, true)) {\n setValueInStorage(\"cly_cmp_id\", getValueFromStorage(self.namespace + \"cly_cmp_id\", false, true));\n setValueInStorage(\"cly_cmp_uid\", getValueFromStorage(self.namespace + \"cly_cmp_uid\", false, true));\n }\n if (getValueFromStorage(self.namespace + \"cly_ignore\", false, true)) {\n setValueInStorage(\"cly_ignore\", getValueFromStorage(self.namespace + \"cly_ignore\", false, true));\n }\n\n // now deleting old data, so we won't migrate again\n removeValueFromStorage(\"cly_id\", false, true);\n removeValueFromStorage(\"cly_id_type\", false, true);\n removeValueFromStorage(\"cly_event\", false, true);\n removeValueFromStorage(\"cly_session\", false, true);\n removeValueFromStorage(\"cly_queue\", false, true);\n removeValueFromStorage(\"cly_cmp_id\", false, true);\n removeValueFromStorage(\"cly_cmp_uid\", false, true);\n removeValueFromStorage(\"cly_ignore\", false, true);\n }\n }\n\n /**\n * Apply modified storage changes\n * @param {String} key - key of storage modified\n * @param {Varies} newValue - new value for storage\n */\n this.onStorageChange = function(key, newValue) {\n log(logLevelEnums.DEBUG, \"onStorageChange, Applying storage changes for key:\", key);\n log(logLevelEnums.DEBUG, \"onStorageChange, Applying storage changes for value:\", newValue);\n switch (key) {\n // queue of requests\n case \"cly_queue\":\n requestQueue = self.deserialize(newValue || \"[]\");\n break;\n // queue of events\n case \"cly_event\":\n eventQueue = self.deserialize(newValue || \"[]\");\n break;\n case \"cly_remote_configs\":\n remoteConfigs = self.deserialize(newValue || \"{}\");\n break;\n case \"cly_ignore\":\n self.ignore_visitor = self.deserialize(newValue);\n break;\n case \"cly_id\":\n self.device_id = newValue;\n break;\n case \"cly_id_type\":\n deviceIdType = self.deserialize(newValue);\n break;\n default:\n // do nothing\n }\n };\n\n /**\n * Expose internal methods to end user for usability\n * @namespace Countly._internals\n * @name Countly._internals\n */\n this._internals = {\n // TODO: looks like we do not use this function. Either use it for something or eliminate.\n store: setValueInStorage,\n getDocWidth: getDocWidth,\n getDocHeight: getDocHeight,\n getViewportHeight: getViewportHeight,\n get_page_coord: get_page_coord,\n get_event_target: get_event_target,\n add_event_listener: add_event_listener,\n createNewObjectFromProperties: createNewObjectFromProperties,\n truncateObject: truncateObject,\n truncateSingleValue: truncateSingleValue,\n stripTrailingSlash: stripTrailingSlash,\n prepareParams: prepareParams,\n sendXmlHttpRequest: sendXmlHttpRequest,\n isResponseValid: isResponseValid,\n getInternalDeviceIdType: getInternalDeviceIdType,\n getMsTimestamp: getMsTimestamp,\n getTimestamp: getTimestamp,\n isResponseValidBroad: isResponseValidBroad,\n secureRandom: secureRandom,\n log: log,\n checkIfLoggingIsOn: checkIfLoggingIsOn,\n getMetrics: getMetrics,\n getUA: getUA,\n prepareRequest: prepareRequest,\n generateUUID: generateUUID,\n sendEventsForced: sendEventsForced,\n isUUID: isUUID,\n isReferrerUsable: isReferrerUsable,\n getId: getStoredIdOrGenerateId,\n heartBeat: heartBeat,\n toRequestQueue: toRequestQueue,\n reportViewDuration: reportViewDuration,\n loadJS: loadJS,\n loadCSS: loadCSS,\n getLastView: getLastView,\n setToken: setToken,\n getToken: getToken,\n showLoader: showLoader,\n hideLoader: hideLoader,\n setValueInStorage: setValueInStorage,\n getValueFromStorage: getValueFromStorage,\n removeValueFromStorage: removeValueFromStorage,\n add_cly_events: add_cly_events,\n processScrollView: processScrollView,\n processScroll: processScroll,\n currentUserAgentString: currentUserAgentString,\n userAgentDeviceDetection: userAgentDeviceDetection,\n userAgentSearchBotDetection: userAgentSearchBotDetection,\n getRequestQueue: getRequestQueue,\n getEventQueue: getEventQueue,\n /**\n * Clear queued data\n * @memberof Countly._internals\n */\n clearQueue: function() {\n requestQueue = [];\n setValueInStorage(\"cly_queue\", []);\n eventQueue = [];\n setValueInStorage(\"cly_event\", []);\n }\n };\n\n /**\n * Health Check Interface:\n * {sendInstantHCRequest} Sends instant health check request\n * {resetAndSaveCounters} Resets and saves health check counters\n * {incrementErrorCount} Increments health check error count\n * {incrementWarningCount} Increments health check warning count\n * {resetCounters} Resets health check counters\n * {saveRequestCounters} Saves health check request counters\n */\n var HealthCheck = {};\n HealthCheck.sendInstantHCRequest = sendInstantHCRequest;\n HealthCheck.resetAndSaveCounters = resetAndSaveCounters;\n HealthCheck.incrementErrorCount = incrementErrorCount;\n HealthCheck.incrementWarningCount = incrementWarningCount;\n HealthCheck.resetCounters = resetCounters;\n HealthCheck.saveRequestCounters = saveRequestCounters;\n /**\n * Increments health check error count\n */\n function incrementErrorCount() {\n self.hcErrorCount++;\n }\n /**\n * Increments health check warning count\n */\n function incrementWarningCount() {\n self.hcWarningCount++;\n }\n /**\n * Resets health check counters\n */\n function resetCounters() {\n self.hcErrorCount = 0;\n self.hcWarningCount = 0;\n self.hcStatusCode = -1;\n self.hcErrorMessage = \"\";\n }\n /**\n * Sets and saves the status code and error message counters \n * @param {number} status - response status code of the request\n * @param {string} responseText - response text of the request\n */\n function saveRequestCounters(status, responseText) {\n self.hcStatusCode = status;\n self.hcErrorMessage = responseText;\n setValueInStorage(healthCheckCounterEnum.statusCode, self.hcStatusCode);\n setValueInStorage(healthCheckCounterEnum.errorMessage, self.hcErrorMessage);\n }\n /**\n * Resets and saves health check counters\n */\n function resetAndSaveCounters() {\n HealthCheck.resetCounters();\n setValueInStorage(healthCheckCounterEnum.errorCount, self.hcErrorCount);\n setValueInStorage(healthCheckCounterEnum.warningCount, self.hcWarningCount);\n setValueInStorage(healthCheckCounterEnum.statusCode, self.hcStatusCode);\n setValueInStorage(healthCheckCounterEnum.errorMessage, self.hcErrorMessage);\n }\n /**\n * Countly health check request sender\n */\n function sendInstantHCRequest() {\n // truncate error message to 1000 characters\n var curbedMessage = truncateSingleValue(self.hcErrorMessage, 1000, \"healthCheck\", log);\n // prepare hc object\n var hc = {\n el: self.hcErrorCount,\n wl: self.hcWarningCount,\n sc: self.hcStatusCode,\n em: JSON.stringify(curbedMessage)\n };\n // prepare request\n var request = {\n hc: JSON.stringify(hc),\n metrics: JSON.stringify({ _app_version: self.app_version })\n };\n // add common request params\n prepareRequest(request);\n // send request\n sendXmlHttpRequest(\"[healthCheck]\", self.url + apiPath, request, function(err, params, status, responseText) {\n if (err) {\n log(logLevelEnums.ERROR, \"[healthCheck] An error occurred. Status: [\" + status + \"], response: [\" + responseText + \"]\");\n }\n else {\n log(logLevelEnums.INFO, \"[healthCheck] Request was successful. Status: [\" + status + \"], response: [\" + responseText + \"]\");\n // reset and save health check counters if request was successful\n HealthCheck.resetAndSaveCounters();\n }\n }, true);\n }\n\n // initialize Countly Class\n this.initialize();\n };\n\n /**\n * Countly class - exposing so plugins can extend its prototype\n * @param {Object} ob - Configuration object\n */\n Countly.CountlyClass = CountlyClass;\n\n /**\n * Initialize Countly object\n * @param {Object} conf - Countly initialization/config {@link Init} object with configuration options\n * @param {string} conf.app_key - app key for your app created in Countly\n * @param {string} conf.device_id - to identify a visitor, will be auto generated if not provided\n * @param {string} conf.url - your Countly server url, you can use your server URL or IP here\n * @param {boolean} [conf.clear_stored_id=false] - set it to true if you want to erase previously stored device ID from the local storage\n * @param {string} [conf.app_version=0.0] - the version of your app or website\n * @param {string=} conf.country_code - country code for your visitor\n * @param {string=} conf.city - name of the city of your visitor\n * @param {string=} conf.ip_address - ip address of your visitor\n * @param {boolean} [conf.debug=false] - output debug info into console\n * @param {boolean} [conf.ignore_bots=true] - option to ignore traffic from bots\n * @param {number} [conf.interval=500] - set an interval how often to check if there is any data to report and report it in milliseconds\n * @param {number} [conf.queue_size=1000] - maximum amount of queued requests to store\n * @param {number} [conf.fail_timeout=60] - set time in seconds to wait after failed connection to server in seconds\n * @param {number} [conf.inactivity_time=20] - after how many minutes user should be counted as inactive, if he did not perform any actions, as mouse move, scroll or keypress\n * @param {number} [conf.session_update=60] - how often in seconds should session be extended\n * @param {number} [conf.max_events=100] - maximum amount of events to send in one batch\n * @deprecated {number} [conf.max_logs=100] - maximum amount of breadcrumbs to store for crash logs\n * @param {number} [conf.max_key_length=128] - maximum size of all string keys\n * @param {number} [conf.max_value_size=256] - maximum size of all values in our key-value pairs (Except \"picture\" field, that has a limit of 4096 chars)\n * @param {number} [conf.max_segmentation_values=30] - max amount of custom (dev provided) segmentation in one event\n * @param {number} [conf.max_breadcrumb_count=100] - maximum amount of breadcrumbs that can be recorded before the oldest one is deleted\n * @param {number} [conf.max_stack_trace_lines_per_thread=30] - maximum amount of stack trace lines would be recorded per thread\n * @param {number} [conf.max_stack_trace_line_length=200] - maximum amount of characters are allowed per stack trace line. This limits also the crash message length\n * @param {array=} conf.ignore_referrers - array with referrers to ignore\n * @param {boolean} [conf.ignore_prefetch=true] - ignore prefetching and pre rendering from counting as real website visits\n * @param {boolean} [conf.rc_automatic_optin_for_ab=true] - opts in the user for A/B testing while fetching the remote config (if true)\n * @param {boolean} [conf.use_explicit_rc_api=false] - set it to true to use the new remote config API\n * @param {boolean} [conf.force_post=false] - force using post method for all requests\n * @param {boolean} [conf.ignore_visitor=false] - ignore this current visitor\n * @param {boolean} [conf.require_consent=false] - Pass true if you are implementing GDPR compatible consent management. It would prevent running any functionality without proper consent\n * @param {boolean} [conf.utm={\"source\":true, \"medium\":true, \"campaign\":true, \"term\":true, \"content\":true}] - Object instructing which UTM parameters to track\n * @param {boolean} [conf.use_session_cookie=true] - Use cookie to track session\n * @param {boolean} [conf.enable_orientation_tracking=true] - Enables orientation tracking at the start of a session\n * @param {array=} [conf.heatmap_whitelist=[]] - array with trustable domains for heatmap reporting\n * @param {number} [conf.session_cookie_timeout=30] - How long till cookie session should expire in minutes\n * @param {boolean|function} [conf.remote_config=false] - Enable automatic remote config fetching, provide callback function to be notified when fetching done\n * @param {string=} [conf.namespace=\"\"] - Have separate namespace of of persistent data\n * @param {boolean=} [conf.track_domains=true] - Set to false to disable domain tracking, so no domain data would be reported\n * @param {Object=} [conf.metrics={}] - provide metrics for this user, or else will try to collect what's possible\n * @param {string} conf.metrics._os - name of platform/operating system\n * @param {string} conf.metrics._os_version - version of platform/operating system\n * @param {string} conf.metrics._device - device name\n * @param {string} conf.metrics._resolution - screen resolution of the device\n * @param {string} conf.metrics._carrier - carrier or operator used for connection\n * @param {string} conf.metrics._density - screen density of the device\n * @param {string} conf.metrics._locale - locale or language of the device in ISO format\n * @param {string} conf.metrics._store - source from where the user came from\n * @param {string} conf.metrics._browser - browser name\n * @param {string} conf.metrics._browser_version - browser version\n * @param {string} conf.metrics._ua - user agent string\n * @param {Object=} [conf.headers={}] - Object to override or add headers to all SDK requests\n * @param {string=} [conf.storage=default] - What type of storage to use, by default uses local storage and would fallback to cookies, but you can set values \"localstorage\" or \"cookies\" to force only specific storage, or use \"none\" to not use any storage and keep everything in memory\n * @returns {Object} countly tracker instance\n * @example\n * Countly.init({\n * //provide your app key that you retrieved from Countly dashboard\n * app_key: \"YOUR_APP_KEY\",\n * //provide your server IP or name. Use try.count.ly for EE trial server.\n * url: \"http://yourdomain.com\"\n * });\n */\n Countly.init = function(conf) {\n conf = conf || {};\n if (Countly.loadAPMScriptsAsync && apmLibrariesNotLoaded) {\n apmLibrariesNotLoaded = false;\n initAfterLoadingAPM(conf);\n return;\n }\n var appKey = conf.app_key || Countly.app_key;\n if (!Countly.i || !Countly.i[appKey]) {\n var inst = new Countly.CountlyClass(conf);\n if (!Countly.i) {\n Countly.i = {};\n for (var key in inst) {\n Countly[key] = inst[key];\n }\n }\n Countly.i[appKey] = inst;\n }\n return Countly.i[appKey];\n };\n\n /**\n * Countly object methods:\n * Countly. \n * CountlyClass: ƒ (ob)\n * DeviceIdType: {DEVELOPER_SUPPLIED: 0, SDK_GENERATED: 1, TEMPORARY_ID: 2}\n * add_consent: ƒ (feature)\n * add_event: ƒ (event)\n * add_log: ƒ (record)\n * app_key: \"YOUR_APP_KEY\"\n * app_version: \"0.0\"\n * begin_session: ƒ (noHeartBeat, force)\n * cancel_event: ƒ (key)\n * change_id: ƒ (newId, merge)\n * check_any_consent: ƒ ()\n * check_consent: ƒ (feature)\n * city: null\n * clearStoredId: false\n * collect_from_facebook: ƒ (custom)\n * collect_from_forms: ƒ (parent, useCustom)\n * country_code: null\n * debug: false\n * deserialize: ƒ (data)\n * device_id: undefined\n * disable_offline_mode: ƒ (device_id)\n * enableOrientationTracking: true\n * enableRatingWidgets: ƒ (params)\n * enable_feedback: ƒ (params)\n * enable_offline_mode: ƒ ()\n * end_event: ƒ (event)\n * end_session: ƒ (sec, force)\n * enrollUserToAb: ƒ (keys)\n * features: (14) ['sessions', 'events', 'views', 'scrolls', 'clicks', 'forms', 'crashes', 'attribution', 'users', 'star-rating', 'location', 'apm', 'feedback', 'remote-config']\n * fetch_remote_config: ƒ (keys, omit_keys, callback)\n * force_post: false\n * getFeedbackWidgetData: ƒ (CountlyFeedbackWidget, callback)\n * getSearchQuery: ƒ ()\n * getViewName: ƒ ()\n * getViewUrl: ƒ ()\n * get_available_feedback_widgets: ƒ (callback)\n * get_device_id: ƒ ()\n * get_device_id_type: ƒ ()\n * get_remote_config: ƒ (key)\n * group_features: ƒ (features)\n * halt: ƒ ()\n * headers: {}\n * heatmapWhitelist: []\n * i: {YOUR_APP_KEY: CountlyClass}\n * ignore_bots: true\n * ignore_prefetch: true\n * ignore_visitor: false\n * init: ƒ (conf)\n * initialize: ƒ ()\n * initializeRatingWidgets: ƒ (enableWidgets)\n * initialize_feedback_popups: ƒ (enableWidgets)\n * ip_address: null\n * loadAPMScriptsAsync: undefined\n * customSourceBoomerang: CDN.BOOMERANG_SRC or basically the cdn link to boomerang.min.js\n * customSourceCountlyBoomerang: CDN.CLY_BOOMERANG_SRC or basically the cdn link to countly_boomerang.js\n * log_error: ƒ (err, segments)\n * maxBreadcrumbCount: 100\n * maxKeyLength: 128\n * maxSegmentationValues: 100\n * maxStackTraceLineLength: 200\n * maxStackTraceLinesPerThread: 30\n * maxValueSize: 256\n * metrics: {}\n * namespace: \"\"\n * onStorageChange: ƒ (key, newValue)\n * onload: []\n * opt_in: ƒ ()\n * opt_out: ƒ ()\n * presentRatingWidgetWithID: ƒ (id)\n * present_feedback_widget: ƒ (presentableFeedback, id, className)\n * q: []\n * rcAutoOptinAb: true\n * recordDirectAttribution: ƒ (campaign_id, campaign_user_id)\n * recordError: ƒ (err, nonfatal, segments)\n * recordRatingWidgetWithID: ƒ (ratingWidget)\n * remote_config: false\n * remove_consent: ƒ (feature)\n * remove_consent_internal: ƒ (feature, enforceConsentUpdate)\n * reportFeedbackWidgetManually: ƒ (CountlyFeedbackWidget, CountlyWidgetData, widgetResult)\n * report_conversion: ƒ (campaign_id, campaign_user_id)\n * report_feedback: ƒ (ratingWidget)\n * report_orientation: ƒ (orientation)\n * report_trace: ƒ (trace)\n * require_consent: false\n * serialize: ƒ (value)\n * session_duration: ƒ (sec)\n * show_feedback_popup: ƒ (id)\n * start_event: ƒ (key)\n * start_time: ƒ ()\n * stop_time: ƒ ()\n * storage: \"default\" but can be \"none\" or \"cookies\" or \"localstorage\" == \"default\"\n * test_mode: false\n * test_mode_eq: false\n * track_clicks: ƒ (parent)\n * track_domains: true\n * track_errors: ƒ (segments)\n * track_forms: ƒ (parent, trackHidden)\n * track_links: ƒ (parent)\n * track_pageview: ƒ (page, ignoreList, viewSegments)\n * track_performance: ƒ (config)\n * track_scrolls: ƒ (parent)\n * track_sessions: ƒ ()\n * track_view: ƒ (page, ignoreList, segments)\n * url: \"https://try.count.ly\" or the URL you have set\n * useExplicitRcApi: false\n * userData: {set: ƒ, unset: ƒ, set_once: ƒ, increment: ƒ, increment_by: ƒ, …}\n * user_details: ƒ (user)\n * utm: {source: true, medium: true, campaign: true, term: true, content: true}\n * _internals: {store: ƒ, getDocWidth: ƒ, getDocHeight: ƒ, getViewportHeight: ƒ, get_page_coord: ƒ, …}\n * \n */\n\n /**\n * PRIVATE METHODS\n * */\n\n /**\n * This is for Async implementation only\n * This should be used to initialize the SDK with APM feature. It loads necessary scripts before initializing the SDK.\n * @param {Object} conf - Countly config object.\n */\n function initAfterLoadingAPM(conf) {\n // TODO: We assume we are in browser context. If browser context checks at top are removed this code should have its own check.\n // TODO: We already have a loadFile and loadJS functions but they are not used here. If readability would improve that way, they can also be considered here.\n\n // Create boomerang script\n var boomerangScript = document.createElement(\"script\");\n var countlyBoomerangScript = document.createElement(\"script\");\n\n // Set boomerang script attributes\n boomerangScript.async = true;\n countlyBoomerangScript.async = true;\n\n // Set boomerang script source\n boomerangScript.src = Countly.customSourceBoomerang || CDN.BOOMERANG_SRC;\n countlyBoomerangScript.src = Countly.customSourceCountlyBoomerang || CDN.CLY_BOOMERANG_SRC;\n\n // Append boomerang script to the head\n document.getElementsByTagName(\"head\")[0].appendChild(boomerangScript);\n document.getElementsByTagName(\"head\")[0].appendChild(countlyBoomerangScript);\n\n var boomLoaded = false;\n var countlyBoomLoaded = false;\n boomerangScript.onload = function() {\n boomLoaded = true;\n };\n countlyBoomerangScript.onload = function() {\n countlyBoomLoaded = true;\n };\n\n var timeoutCounter = 0;\n var intervalDuration = 50;\n var timeoutLimit = 1500; // TODO: Configurable? Mb with Countly.apmScriptLoadTimeout?\n // init Countly only after boomerang is loaded\n var intervalID = setInterval(function() {\n timeoutCounter += intervalDuration;\n if ((boomLoaded && countlyBoomLoaded) || (timeoutCounter >= timeoutLimit)) {\n if (Countly.debug) {\n var message = \"BoomerangJS loaded:[\" + boomLoaded + \"], countly_boomerang loaded:[\" + countlyBoomLoaded + \"].\";\n if (boomLoaded && countlyBoomLoaded) {\n message = \"[DEBUG] \" + message;\n // eslint-disable-next-line no-console\n console.log(message);\n }\n else {\n message = \"[WARNING] \" + message + \" Initializing without APM.\";\n // eslint-disable-next-line no-console\n console.warn(message);\n }\n }\n Countly.init(conf);\n clearInterval(intervalID);\n }\n }, intervalDuration);\n }\n\n /**\n * Get selected values from multi select input\n * @param {HTMLElement} input - select with multi true option\n * @returns {String} coma concatenated values\n */\n function getMultiSelectValues(input) {\n var values = [];\n if (typeof input.options !== \"undefined\") {\n for (var j = 0; j < input.options.length; j++) {\n if (input.options[j].selected) {\n values.push(input.options[j].value);\n }\n }\n }\n return values.join(\", \");\n }\n\n /**\n * Return a crypto-safe random string\n * @memberof Countly._internals\n * @returns {string} - random string\n */\n function secureRandom() {\n var id = \"xxxxxxxx\";\n id = replacePatternWithRandomValues(id, \"[x]\");\n\n // timestamp in milliseconds\n var timestamp = Date.now().toString();\n\n return (id + timestamp);\n }\n\n /**\n * Generate random UUID value\n * @memberof Countly._internals\n * @returns {String} random UUID value\n */\n function generateUUID() {\n var uuid = \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\";\n uuid = replacePatternWithRandomValues(uuid, \"[xy]\");\n return uuid;\n }\n\n /**\n * Generate random value based on pattern\n * \n * @param {string} str - string to replace\n * @param {string} pattern - pattern to replace\n * @returns {string} - replaced string\n */\n function replacePatternWithRandomValues(str, pattern) {\n var d = new Date().getTime();\n var regex = new RegExp(pattern, \"g\");\n return str.replace(regex, function(c) {\n var r = (d + Math.random() * 16) % 16 | 0;\n return (c === \"x\" ? r : (r & 0x3 | 0x8)).toString(16);\n });\n }\n\n /**\n * Get unix timestamp\n * @memberof Countly._internals\n * @returns {Number} unix timestamp\n */\n function getTimestamp() {\n return Math.floor(new Date().getTime() / 1000);\n }\n\n var lastMsTs = 0;\n /**\n * Get unique timestamp in milliseconds\n * @memberof Countly._internals\n * @returns {Number} milliseconds timestamp\n */\n function getMsTimestamp() {\n var ts = new Date().getTime();\n if (lastMsTs >= ts) {\n lastMsTs++;\n }\n else {\n lastMsTs = ts;\n }\n return lastMsTs;\n }\n\n /**\n * Get config value from multiple sources\n * like config object, global object or fallback value\n * @param {String} key - config key\n * @param {Object} ob - config object\n * @param {Varies} override - fallback value\n * @returns {Varies} value to be used as config\n */\n function getConfig(key, ob, override) {\n if (ob && Object.keys(ob).length) {\n if (typeof ob[key] !== \"undefined\") {\n return ob[key];\n }\n }\n else if (typeof Countly[key] !== \"undefined\") {\n return Countly[key];\n }\n return override;\n }\n\n /**\n * Dispatch errors to instances that lister to errors\n * @param {Error} error - Error object\n * @param {Boolean} fatality - fatal if false and nonfatal if true\n * @param {Object} segments - custom crash segments\n */\n function dispatchErrors(error, fatality, segments) {\n // Check each instance like Countly.i[app_key_1], Countly.i[app_key_2] ...\n for (var app_key in Countly.i) {\n // If track_errors is enabled for that instance\n if (Countly.i[app_key].tracking_crashes) {\n // Trigger recordError function for that instance\n Countly.i[app_key].recordError(error, fatality, segments);\n }\n }\n }\n\n /**\n * Convert JSON object to URL encoded query parameter string\n * @memberof Countly._internals\n * @param {Object} params - object with query parameters\n * @returns {String} URL encode query string\n */\n function prepareParams(params) {\n var str = [];\n for (var i in params) {\n str.push(i + \"=\" + encodeURIComponent(params[i]));\n }\n return str.join(\"&\");\n }\n\n /**\n * Removing trailing slashes\n * @memberof Countly._internals\n * @param {String} str - string from which to remove trailing slash\n * @returns {String} modified string\n */\n function stripTrailingSlash(str) {\n if (typeof str === \"string\") {\n if (str.substring(str.length - 1) === \"/\") {\n return str.substring(0, str.length - 1);\n }\n }\n return str;\n }\n\n /**\n * Retrieve only specific properties from object\n * @memberof Countly._internals\n * @param {Object} orig - original object\n * @param {Array} props - array with properties to get from object\n * @returns {Object} new object with requested properties\n */\n function createNewObjectFromProperties(orig, props) {\n var ob = {};\n var prop;\n for (var i = 0, len = props.length; i < len; i++) {\n prop = props[i];\n if (typeof orig[prop] !== \"undefined\") {\n ob[prop] = orig[prop];\n }\n }\n return ob;\n }\n\n /**\n * Add specified properties to an object from another object\n * @memberof Countly._internals\n * @param {Object} orig - original object\n * @param {Object} transferOb - object to copy values from\n * @param {Array} props - array with properties to get from object\n * @returns {Object} original object with additional requested properties\n */\n function addNewProperties(orig, transferOb, props) {\n if (!props) {\n return;\n }\n var prop;\n for (var i = 0, len = props.length; i < len; i++) {\n prop = props[i];\n if (typeof transferOb[prop] !== \"undefined\") {\n orig[prop] = transferOb[prop];\n }\n }\n return orig;\n }\n\n /**\n * Truncates an object's key/value pairs to a certain length\n * @param {Object} obj - original object to be truncated\n * @param {Number} keyLimit - limit for key length\n * @param {Number} valueLimit - limit for value length\n * @param {Number} segmentLimit - limit for segments pairs\n * @param {string} errorLog - prefix for error log\n * @param {function} logCall - internal logging function\n * @returns {Object} - the new truncated object\n */\n function truncateObject(obj, keyLimit, valueLimit, segmentLimit, errorLog, logCall) {\n var ob = {};\n if (obj) {\n if (Object.keys(obj).length > segmentLimit) {\n var resizedObj = {};\n var i = 0;\n for (var e in obj) {\n if (i < segmentLimit) {\n resizedObj[e] = obj[e];\n i++;\n }\n }\n obj = resizedObj;\n }\n for (var key in obj) {\n var newKey = truncateSingleValue(key, keyLimit, errorLog, logCall);\n var newValue = truncateSingleValue(obj[key], valueLimit, errorLog, logCall);\n ob[newKey] = newValue;\n }\n }\n return ob;\n }\n\n /**\n * Truncates a single value to a certain length\n * @param {string|number} str - original value to be truncated\n * @param {Number} limit - limit length\n * @param {string} errorLog - prefix for error log\n * @param {function} logCall - internal logging function\n * @returns {string|number} - the new truncated value\n */\n function truncateSingleValue(str, limit, errorLog, logCall) {\n var newStr = str;\n if (typeof str === \"number\") {\n str = str.toString();\n }\n if (typeof str === \"string\") {\n if (str.length > limit) {\n newStr = str.substring(0, limit);\n logCall(logLevelEnums.DEBUG, errorLog + \", Key: [ \" + str + \" ] is longer than accepted length. It will be truncated.\");\n }\n }\n return newStr;\n }\n\n /**\n * Polyfill to get closest parent matching nodeName\n * @param {HTMLElement} el - element from which to search\n * @param {String} nodeName - tag/node name\n * @returns {HTMLElement} closest parent element\n */\n var get_closest_element = function(el, nodeName) {\n nodeName = nodeName.toUpperCase();\n while (el) {\n if (el.nodeName.toUpperCase() === nodeName) {\n return el;\n }\n el = el.parentElement;\n }\n };\n\n /**\n * Listen to specific browser event\n * @memberof Countly._internals\n * @param {HTMLElement} element - HTML element that should listen to event\n * @param {String} type - event name or action\n * @param {Function} listener - callback when event is fired\n */\n var add_event_listener = function(element, type, listener) {\n if (element === null || typeof element === \"undefined\") { // element can be null so lets check it first\n if (checkIfLoggingIsOn()) {\n // eslint-disable-next-line no-console\n console.warn(\"[WARNING] [Countly] add_event_listener, Can't bind [\" + type + \"] event to nonexisting element\");\n }\n return;\n }\n if (typeof element.addEventListener !== \"undefined\") {\n element.addEventListener(type, listener, false);\n }\n // for old browser use attachEvent instead\n else {\n element.attachEvent(\"on\" + type, listener);\n }\n };\n\n /**\n * Get element that fired event\n * @memberof Countly._internals\n * @param {Event} event - event that was filed\n * @returns {HTMLElement} HTML element that caused event to fire\n */\n var get_event_target = function(event) {\n if (!event) {\n return window.event.srcElement;\n }\n if (typeof event.target !== \"undefined\") {\n return event.target;\n }\n return event.srcElement;\n };\n\n /**\n * Returns raw user agent string\n * @memberof Countly._internals\n * @param {string} uaOverride - a string value to pass instead of ua value\n * @returns {string} currentUserAgentString - raw user agent string\n */\n function currentUserAgentString(uaOverride) {\n if (uaOverride) {\n return uaOverride;\n }\n\n var ua_raw = navigator.userAgent;\n // check if userAgentData is supported and userAgent is not available, use it\n if (!ua_raw) {\n if (navigator.userAgentData) {\n // turn brands array into string\n ua_raw = navigator.userAgentData.brands.map(function(e) {\n return e.brand + \":\" + e.version;\n }).join();\n // add mobile info\n ua_raw += (navigator.userAgentData.mobile ? \" mobi \" : \" \");\n // add platform info\n ua_raw += navigator.userAgentData.platform;\n }\n }\n // RAW USER AGENT STRING\n return ua_raw;\n }\n\n /**\n * Returns device type information according to user agent string\n * @memberof Countly._internals\n * @param {string} uaOverride - a string value to pass instead of ua value\n * @returns {string} userAgentDeviceDetection - current device type (desktop, tablet, phone)\n */\n function userAgentDeviceDetection(uaOverride) {\n var userAgent;\n // TODO: refactor here\n if (uaOverride) {\n userAgent = uaOverride;\n }\n else if (navigator.userAgentData.mobile) {\n return \"phone\";\n }\n else {\n userAgent = currentUserAgentString();\n }\n // make it lowercase for regex to work properly\n userAgent = userAgent.toLowerCase();\n\n // assign the default device\n var device = \"desktop\";\n\n // regexps corresponding to tablets or phones that can be found in userAgent string\n var tabletCheck = /(ipad|tablet|(android(?!.*mobile))|(windows(?!.*phone)(.*touch))|kindle|playbook|silk|(puffin(?!.*(IP|AP|WP))))/;\n var phoneCheck = /(mobi|ipod|phone|blackberry|opera mini|fennec|minimo|symbian|psp|nintendo ds|archos|skyfire|puffin|blazer|bolt|gobrowser|iris|maemo|semc|teashark|uzard)/;\n\n // check whether the regexp values corresponds to something in the user agent string\n if (tabletCheck.test(userAgent)) {\n device = \"tablet\";\n }\n else if (phoneCheck.test(userAgent)) {\n device = \"phone\";\n }\n\n // set the device type\n return device;\n }\n\n /**\n * Returns information regarding if the current user is a search bot or not\n * @memberof Countly._internals\n * @param {string} uaOverride - a string value to pass instead of ua value\n * @returns {boolean} userAgentSearchBotDetection - if a search bot is reaching the site or not\n */\n function userAgentSearchBotDetection(uaOverride) {\n // search bot regexp\n var searchBotRE = /(CountlySiteBot|nuhk|Googlebot|GoogleSecurityScanner|Yammybot|Openbot|Slurp|MSNBot|Ask Jeeves\\/Teoma|ia_archiver|bingbot|Google Web Preview|Mediapartners-Google|AdsBot-Google|Baiduspider|Ezooms|YahooSeeker|AltaVista|AVSearch|Mercator|Scooter|InfoSeek|Ultraseek|Lycos|Wget|YandexBot|Yandex|YaDirectFetcher|SiteBot|Exabot|AhrefsBot|MJ12bot|TurnitinBot|magpie-crawler|Nutch Crawler|CMS Crawler|rogerbot|Domnutch|ssearch_bot|XoviBot|netseer|digincore|fr-crawler|wesee|AliasIO|contxbot|PingdomBot|BingPreview|HeadlessChrome)/;\n // true if the user agent string contains a search bot string pattern\n return searchBotRE.test(uaOverride || currentUserAgentString());\n }\n\n /**\n * Modify event to set standard coordinate properties if they are not available\n * @memberof Countly._internals\n * @param {Event} e - event object\n * @returns {Event} modified event object\n */\n function get_page_coord(e) {\n // checking if pageY and pageX is already available\n if (typeof e.pageY === \"undefined\"\n && typeof e.clientX === \"number\"\n && document.documentElement) {\n // if not, then add scrolling positions\n e.pageX = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;\n e.pageY = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;\n }\n // return e which now contains pageX and pageY attributes\n return e;\n }\n\n /**\n * Get height of whole document\n * @memberof Countly._internals\n * @returns {Number} height in pixels\n */\n function getDocHeight() {\n var D = document;\n return Math.max(\n Math.max(D.body.scrollHeight, D.documentElement.scrollHeight),\n Math.max(D.body.offsetHeight, D.documentElement.offsetHeight),\n Math.max(D.body.clientHeight, D.documentElement.clientHeight)\n );\n }\n\n /**\n * Get width of whole document\n * @memberof Countly._internals\n * @returns {Number} width in pixels\n */\n function getDocWidth() {\n var D = document;\n return Math.max(\n Math.max(D.body.scrollWidth, D.documentElement.scrollWidth),\n Math.max(D.body.offsetWidth, D.documentElement.offsetWidth),\n Math.max(D.body.clientWidth, D.documentElement.clientWidth)\n );\n }\n\n /**\n * Get height of viewable area\n * @memberof Countly._internals\n * @returns {Number} height in pixels\n */\n function getViewportHeight() {\n var D = document;\n return Math.min(\n Math.min(D.body.clientHeight, D.documentElement.clientHeight),\n Math.min(D.body.offsetHeight, D.documentElement.offsetHeight),\n window.innerHeight\n );\n }\n\n /**\n * Get device's orientation\n * @returns {String} device orientation\n */\n function getOrientation() {\n return window.innerWidth > window.innerHeight ? \"landscape\" : \"portrait\";\n }\n\n /**\n * Monitor parallel storage changes like other opened tabs\n */\n window.addEventListener(\"storage\", function(e) {\n var parts = (e.key + \"\").split(\"/\");\n var key = parts.pop();\n var appKey = parts.pop();\n\n if (Countly.i && Countly.i[appKey]) {\n Countly.i[appKey].onStorageChange(key, e.newValue);\n }\n });\n\n /**\n * Load external js files\n * @param {String} tag - Tag/node name to load file in\n * @param {String} attr - Attribute name for type\n * @param {String} type - Type value\n * @param {String} src - Attribute name for file path\n * @param {String} data - File path\n * @param {Function} callback - callback when done\n */\n function loadFile(tag, attr, type, src, data, callback) {\n var fileRef = document.createElement(tag);\n var loaded;\n fileRef.setAttribute(attr, type);\n fileRef.setAttribute(src, data);\n var callbackFunction = function() {\n if (!loaded) {\n callback();\n }\n loaded = true;\n };\n if (callback) {\n fileRef.onreadystatechange = callbackFunction;\n fileRef.onload = callbackFunction;\n }\n document.getElementsByTagName(\"head\")[0].appendChild(fileRef);\n }\n\n /**\n * Load external js files\n * @memberof Countly._internals\n * @param {String} js - path to JS file\n * @param {Function} callback - callback when done\n */\n function loadJS(js, callback) {\n loadFile(\"script\", \"type\", \"text/javascript\", \"src\", js, callback);\n }\n\n /**\n * Load external css files\n * @memberof Countly._internals\n * @param {String} css - path to CSS file\n * @param {Function} callback - callback when done\n */\n function loadCSS(css, callback) {\n loadFile(\"link\", \"rel\", \"stylesheet\", \"href\", css, callback);\n }\n\n /**\n * Show loader UI when loading external data\n * @memberof Countly._internals\n */\n function showLoader() {\n var loader = document.getElementById(\"cly-loader\");\n if (!loader) {\n var css = \"#cly-loader {height: 4px; width: 100%; position: absolute; z-index: 99999; overflow: hidden; background-color: #fff; top:0px; left:0px;}\"\n + \"#cly-loader:before{display: block; position: absolute; content: ''; left: -200px; width: 200px; height: 4px; background-color: #2EB52B; animation: cly-loading 2s linear infinite;}\"\n + \"@keyframes cly-loading { from {left: -200px; width: 30%;} 50% {width: 30%;} 70% {width: 70%;} 80% { left: 50%;} 95% {left: 120%;} to {left: 100%;}}\";\n var head = document.head || document.getElementsByTagName(\"head\")[0];\n var style = document.createElement(\"style\");\n style.type = \"text/css\";\n if (style.styleSheet) {\n style.styleSheet.cssText = css;\n }\n else {\n style.appendChild(document.createTextNode(css));\n }\n head.appendChild(style);\n loader = document.createElement(\"div\");\n loader.setAttribute(\"id\", \"cly-loader\");\n document.body.onload = function() {\n // check if hideLoader is on and if so return\n if (Countly.showLoaderProtection) {\n if (checkIfLoggingIsOn()) {\n // eslint-disable-next-line no-console\n console.warn(\"[WARNING] [Countly] showloader, Loader is already on\");\n }\n return;\n }\n try {\n document.body.appendChild(loader);\n }\n catch (e) {\n if (checkIfLoggingIsOn()) {\n // eslint-disable-next-line no-console\n console.error(\"[ERROR] [Countly] showLoader, Body is not loaded for loader to append: \" + e);\n }\n }\n };\n }\n loader.style.display = \"block\";\n }\n\n /**\n * Checks if debug is true and console is available in Countly object\n * @memberof Countly._internals \n * @returns {Boolean} true if debug is true and console is available in Countly object\n */\n function checkIfLoggingIsOn() {\n // check if logging is enabled\n if (Countly && Countly.debug && typeof console !== \"undefined\") {\n return true;\n }\n return false;\n }\n\n /**\n * Hide loader UI\n * @memberof Countly._internals\n */\n function hideLoader() {\n // Inform showLoader that it should not append the loader\n Countly.showLoaderProtection = true;\n var loader = document.getElementById(\"cly-loader\");\n if (loader) {\n loader.style.display = \"none\";\n }\n }\n\n /**\n * Overwrite serialization function for extending SDK with encryption, etc\n * @param {any} value - value to serialize\n * @return {string} serialized value\n * */\n Countly.serialize = function(value) {\n // Convert object values to JSON\n if (typeof value === \"object\") {\n value = JSON.stringify(value);\n }\n return value;\n };\n\n /**\n * Overwrite deserialization function for extending SDK with encryption, etc\n * @param {string} data - value to deserialize\n * @return {varies} deserialized value\n * */\n Countly.deserialize = function(data) {\n if (data === \"\") { // we expect string or null only. Empty sting would throw an error.\n return data;\n }\n // Try to parse JSON...\n try {\n data = JSON.parse(data);\n }\n catch (e) {\n if (checkIfLoggingIsOn()) {\n // eslint-disable-next-line no-console\n console.warn(\"[WARNING] [Countly] deserialize, Could not parse the file:[\" + data + \"], error: \" + e);\n }\n }\n\n return data;\n };\n\n /**\n * Overwrite a way to retrieve view name\n * @return {string} view name\n * */\n Countly.getViewName = function() {\n return window.location.pathname;\n };\n\n /**\n * Overwrite a way to retrieve view url\n * @return {string} view url\n * */\n Countly.getViewUrl = function() {\n return window.location.pathname;\n };\n\n /**\n * Overwrite a way to get search query\n * @return {string} view url\n * */\n Countly.getSearchQuery = function() {\n return window.location.search;\n };\n\n /**\n * Possible device Id types are: DEVELOPER_SUPPLIED, SDK_GENERATED, TEMPORARY_ID\n * @enum DeviceIdType\n * */\n Countly.DeviceIdType = {\n DEVELOPER_SUPPLIED: DeviceIdTypeInternalEnums.DEVELOPER_SUPPLIED,\n SDK_GENERATED: DeviceIdTypeInternalEnums.SDK_GENERATED,\n TEMPORARY_ID: DeviceIdTypeInternalEnums.TEMPORARY_ID\n };\n return Countly;\n}));\n","import arrayWithHoles from \"./arrayWithHoles\";\nimport iterableToArrayLimit from \"./iterableToArrayLimit\";\nimport nonIterableRest from \"./nonIterableRest\";\nexport default function _slicedToArray(arr, i) {\n return arrayWithHoles(arr) || iterableToArrayLimit(arr, i) || nonIterableRest();\n}","export default function _arrayWithHoles(arr) {\n if (Array.isArray(arr)) return arr;\n}","export default function _iterableToArrayLimit(arr, i) {\n if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === \"[object Arguments]\")) {\n return;\n }\n\n var _arr = [];\n var _n = true;\n var _d = false;\n var _e = undefined;\n\n try {\n for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {\n _arr.push(_s.value);\n\n if (i && _arr.length === i) break;\n }\n } catch (err) {\n _d = true;\n _e = err;\n } finally {\n try {\n if (!_n && _i[\"return\"] != null) _i[\"return\"]();\n } finally {\n if (_d) throw _e;\n }\n }\n\n return _arr;\n}","export default function _nonIterableRest() {\n throw new TypeError(\"Invalid attempt to destructure non-iterable instance\");\n}","export default {\n disabled: false\n};","import React from 'react';\nexport default React.createContext(null);","import _objectWithoutPropertiesLoose from \"@babel/runtime/helpers/esm/objectWithoutPropertiesLoose\";\nimport _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport ReactDOM from 'react-dom';\nimport config from './config';\nimport { timeoutsShape } from './utils/PropTypes';\nimport TransitionGroupContext from './TransitionGroupContext';\nexport var UNMOUNTED = 'unmounted';\nexport var EXITED = 'exited';\nexport var ENTERING = 'entering';\nexport var ENTERED = 'entered';\nexport var EXITING = 'exiting';\n/**\n * The Transition component lets you describe a transition from one component\n * state to another _over time_ with a simple declarative API. Most commonly\n * it's used to animate the mounting and unmounting of a component, but can also\n * be used to describe in-place transition states as well.\n *\n * ---\n *\n * **Note**: `Transition` is a platform-agnostic base component. If you're using\n * transitions in CSS, you'll probably want to use\n * [`CSSTransition`](https://reactcommunity.org/react-transition-group/css-transition)\n * instead. It inherits all the features of `Transition`, but contains\n * additional features necessary to play nice with CSS transitions (hence the\n * name of the component).\n *\n * ---\n *\n * By default the `Transition` component does not alter the behavior of the\n * component it renders, it only tracks \"enter\" and \"exit\" states for the\n * components. It's up to you to give meaning and effect to those states. For\n * example we can add styles to a component when it enters or exits:\n *\n * ```jsx\n * import { Transition } from 'react-transition-group';\n *\n * const duration = 300;\n *\n * const defaultStyle = {\n * transition: `opacity ${duration}ms ease-in-out`,\n * opacity: 0,\n * }\n *\n * const transitionStyles = {\n * entering: { opacity: 1 },\n * entered: { opacity: 1 },\n * exiting: { opacity: 0 },\n * exited: { opacity: 0 },\n * };\n *\n * const Fade = ({ in: inProp }) => (\n * \n * {state => (\n *
\n * I'm a fade Transition!\n *
\n * )}\n * \n * );\n * ```\n *\n * There are 4 main states a Transition can be in:\n * - `'entering'`\n * - `'entered'`\n * - `'exiting'`\n * - `'exited'`\n *\n * Transition state is toggled via the `in` prop. When `true` the component\n * begins the \"Enter\" stage. During this stage, the component will shift from\n * its current transition state, to `'entering'` for the duration of the\n * transition and then to the `'entered'` stage once it's complete. Let's take\n * the following example (we'll use the\n * [useState](https://reactjs.org/docs/hooks-reference.html#usestate) hook):\n *\n * ```jsx\n * function App() {\n * const [inProp, setInProp] = useState(false);\n * return (\n *
\n * );\n * }\n * ```\n *\n * When the button is clicked the component will shift to the `'entering'` state\n * and stay there for 500ms (the value of `timeout`) before it finally switches\n * to `'entered'`.\n *\n * When `in` is `false` the same thing happens except the state moves from\n * `'exiting'` to `'exited'`.\n */\n\nvar Transition =\n/*#__PURE__*/\nfunction (_React$Component) {\n _inheritsLoose(Transition, _React$Component);\n\n function Transition(props, context) {\n var _this;\n\n _this = _React$Component.call(this, props, context) || this;\n var parentGroup = context; // In the context of a TransitionGroup all enters are really appears\n\n var appear = parentGroup && !parentGroup.isMounting ? props.enter : props.appear;\n var initialStatus;\n _this.appearStatus = null;\n\n if (props.in) {\n if (appear) {\n initialStatus = EXITED;\n _this.appearStatus = ENTERING;\n } else {\n initialStatus = ENTERED;\n }\n } else {\n if (props.unmountOnExit || props.mountOnEnter) {\n initialStatus = UNMOUNTED;\n } else {\n initialStatus = EXITED;\n }\n }\n\n _this.state = {\n status: initialStatus\n };\n _this.nextCallback = null;\n return _this;\n }\n\n Transition.getDerivedStateFromProps = function getDerivedStateFromProps(_ref, prevState) {\n var nextIn = _ref.in;\n\n if (nextIn && prevState.status === UNMOUNTED) {\n return {\n status: EXITED\n };\n }\n\n return null;\n }; // getSnapshotBeforeUpdate(prevProps) {\n // let nextStatus = null\n // if (prevProps !== this.props) {\n // const { status } = this.state\n // if (this.props.in) {\n // if (status !== ENTERING && status !== ENTERED) {\n // nextStatus = ENTERING\n // }\n // } else {\n // if (status === ENTERING || status === ENTERED) {\n // nextStatus = EXITING\n // }\n // }\n // }\n // return { nextStatus }\n // }\n\n\n var _proto = Transition.prototype;\n\n _proto.componentDidMount = function componentDidMount() {\n this.updateStatus(true, this.appearStatus);\n };\n\n _proto.componentDidUpdate = function componentDidUpdate(prevProps) {\n var nextStatus = null;\n\n if (prevProps !== this.props) {\n var status = this.state.status;\n\n if (this.props.in) {\n if (status !== ENTERING && status !== ENTERED) {\n nextStatus = ENTERING;\n }\n } else {\n if (status === ENTERING || status === ENTERED) {\n nextStatus = EXITING;\n }\n }\n }\n\n this.updateStatus(false, nextStatus);\n };\n\n _proto.componentWillUnmount = function componentWillUnmount() {\n this.cancelNextCallback();\n };\n\n _proto.getTimeouts = function getTimeouts() {\n var timeout = this.props.timeout;\n var exit, enter, appear;\n exit = enter = appear = timeout;\n\n if (timeout != null && typeof timeout !== 'number') {\n exit = timeout.exit;\n enter = timeout.enter; // TODO: remove fallback for next major\n\n appear = timeout.appear !== undefined ? timeout.appear : enter;\n }\n\n return {\n exit: exit,\n enter: enter,\n appear: appear\n };\n };\n\n _proto.updateStatus = function updateStatus(mounting, nextStatus) {\n if (mounting === void 0) {\n mounting = false;\n }\n\n if (nextStatus !== null) {\n // nextStatus will always be ENTERING or EXITING.\n this.cancelNextCallback();\n var node = ReactDOM.findDOMNode(this);\n\n if (nextStatus === ENTERING) {\n this.performEnter(node, mounting);\n } else {\n this.performExit(node);\n }\n } else if (this.props.unmountOnExit && this.state.status === EXITED) {\n this.setState({\n status: UNMOUNTED\n });\n }\n };\n\n _proto.performEnter = function performEnter(node, mounting) {\n var _this2 = this;\n\n var enter = this.props.enter;\n var appearing = this.context ? this.context.isMounting : mounting;\n var timeouts = this.getTimeouts();\n var enterTimeout = appearing ? timeouts.appear : timeouts.enter; // no enter animation skip right to ENTERED\n // if we are mounting and running this it means appear _must_ be set\n\n if (!mounting && !enter || config.disabled) {\n this.safeSetState({\n status: ENTERED\n }, function () {\n _this2.props.onEntered(node);\n });\n return;\n }\n\n this.props.onEnter(node, appearing);\n this.safeSetState({\n status: ENTERING\n }, function () {\n _this2.props.onEntering(node, appearing);\n\n _this2.onTransitionEnd(node, enterTimeout, function () {\n _this2.safeSetState({\n status: ENTERED\n }, function () {\n _this2.props.onEntered(node, appearing);\n });\n });\n });\n };\n\n _proto.performExit = function performExit(node) {\n var _this3 = this;\n\n var exit = this.props.exit;\n var timeouts = this.getTimeouts(); // no exit animation skip right to EXITED\n\n if (!exit || config.disabled) {\n this.safeSetState({\n status: EXITED\n }, function () {\n _this3.props.onExited(node);\n });\n return;\n }\n\n this.props.onExit(node);\n this.safeSetState({\n status: EXITING\n }, function () {\n _this3.props.onExiting(node);\n\n _this3.onTransitionEnd(node, timeouts.exit, function () {\n _this3.safeSetState({\n status: EXITED\n }, function () {\n _this3.props.onExited(node);\n });\n });\n });\n };\n\n _proto.cancelNextCallback = function cancelNextCallback() {\n if (this.nextCallback !== null) {\n this.nextCallback.cancel();\n this.nextCallback = null;\n }\n };\n\n _proto.safeSetState = function safeSetState(nextState, callback) {\n // This shouldn't be necessary, but there are weird race conditions with\n // setState callbacks and unmounting in testing, so always make sure that\n // we can cancel any pending setState callbacks after we unmount.\n callback = this.setNextCallback(callback);\n this.setState(nextState, callback);\n };\n\n _proto.setNextCallback = function setNextCallback(callback) {\n var _this4 = this;\n\n var active = true;\n\n this.nextCallback = function (event) {\n if (active) {\n active = false;\n _this4.nextCallback = null;\n callback(event);\n }\n };\n\n this.nextCallback.cancel = function () {\n active = false;\n };\n\n return this.nextCallback;\n };\n\n _proto.onTransitionEnd = function onTransitionEnd(node, timeout, handler) {\n this.setNextCallback(handler);\n var doesNotHaveTimeoutOrListener = timeout == null && !this.props.addEndListener;\n\n if (!node || doesNotHaveTimeoutOrListener) {\n setTimeout(this.nextCallback, 0);\n return;\n }\n\n if (this.props.addEndListener) {\n this.props.addEndListener(node, this.nextCallback);\n }\n\n if (timeout != null) {\n setTimeout(this.nextCallback, timeout);\n }\n };\n\n _proto.render = function render() {\n var status = this.state.status;\n\n if (status === UNMOUNTED) {\n return null;\n }\n\n var _this$props = this.props,\n children = _this$props.children,\n childProps = _objectWithoutPropertiesLoose(_this$props, [\"children\"]); // filter props for Transtition\n\n\n delete childProps.in;\n delete childProps.mountOnEnter;\n delete childProps.unmountOnExit;\n delete childProps.appear;\n delete childProps.enter;\n delete childProps.exit;\n delete childProps.timeout;\n delete childProps.addEndListener;\n delete childProps.onEnter;\n delete childProps.onEntering;\n delete childProps.onEntered;\n delete childProps.onExit;\n delete childProps.onExiting;\n delete childProps.onExited;\n\n if (typeof children === 'function') {\n // allows for nested Transitions\n return React.createElement(TransitionGroupContext.Provider, {\n value: null\n }, children(status, childProps));\n }\n\n var child = React.Children.only(children);\n return (// allows for nested Transitions\n React.createElement(TransitionGroupContext.Provider, {\n value: null\n }, React.cloneElement(child, childProps))\n );\n };\n\n return Transition;\n}(React.Component);\n\nTransition.contextType = TransitionGroupContext;\nTransition.propTypes = process.env.NODE_ENV !== \"production\" ? {\n /**\n * A `function` child can be used instead of a React element. This function is\n * called with the current transition status (`'entering'`, `'entered'`,\n * `'exiting'`, `'exited'`), which can be used to apply context\n * specific props to a component.\n *\n * ```jsx\n * \n * {state => (\n * \n * )}\n * \n * ```\n */\n children: PropTypes.oneOfType([PropTypes.func.isRequired, PropTypes.element.isRequired]).isRequired,\n\n /**\n * Show the component; triggers the enter or exit states\n */\n in: PropTypes.bool,\n\n /**\n * By default the child component is mounted immediately along with\n * the parent `Transition` component. If you want to \"lazy mount\" the component on the\n * first `in={true}` you can set `mountOnEnter`. After the first enter transition the component will stay\n * mounted, even on \"exited\", unless you also specify `unmountOnExit`.\n */\n mountOnEnter: PropTypes.bool,\n\n /**\n * By default the child component stays mounted after it reaches the `'exited'` state.\n * Set `unmountOnExit` if you'd prefer to unmount the component after it finishes exiting.\n */\n unmountOnExit: PropTypes.bool,\n\n /**\n * Normally a component is not transitioned if it is shown when the\n * `` component mounts. If you want to transition on the first\n * mount set `appear` to `true`, and the component will transition in as soon\n * as the `` mounts.\n *\n * > **Note**: there are no special appear states like `appearing`/`appeared`, this prop\n * > only adds an additional enter transition. However, in the\n * > `` component that first enter transition does result in\n * > additional `.appear-*` classes, that way you can choose to style it\n * > differently.\n */\n appear: PropTypes.bool,\n\n /**\n * Enable or disable enter transitions.\n */\n enter: PropTypes.bool,\n\n /**\n * Enable or disable exit transitions.\n */\n exit: PropTypes.bool,\n\n /**\n * The duration of the transition, in milliseconds.\n * Required unless `addEndListener` is provided.\n *\n * You may specify a single timeout for all transitions:\n *\n * ```jsx\n * timeout={500}\n * ```\n *\n * or individually:\n *\n * ```jsx\n * timeout={{\n * appear: 500,\n * enter: 300,\n * exit: 500,\n * }}\n * ```\n *\n * - `appear` defaults to the value of `enter`\n * - `enter` defaults to `0`\n * - `exit` defaults to `0`\n *\n * @type {number | { enter?: number, exit?: number, appear?: number }}\n */\n timeout: function timeout(props) {\n var pt = timeoutsShape;\n if (!props.addEndListener) pt = pt.isRequired;\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 return pt.apply(void 0, [props].concat(args));\n },\n\n /**\n * Add a custom transition end trigger. Called with the transitioning\n * DOM node and a `done` callback. Allows for more fine grained transition end\n * logic. **Note:** Timeouts are still used as a fallback if provided.\n *\n * ```jsx\n * addEndListener={(node, done) => {\n * // use the css transitionend event to mark the finish of a transition\n * node.addEventListener('transitionend', done, false);\n * }}\n * ```\n */\n addEndListener: PropTypes.func,\n\n /**\n * Callback fired before the \"entering\" status is applied. An extra parameter\n * `isAppearing` is supplied to indicate if the enter stage is occurring on the initial mount\n *\n * @type Function(node: HtmlElement, isAppearing: bool) -> void\n */\n onEnter: PropTypes.func,\n\n /**\n * Callback fired after the \"entering\" status is applied. An extra parameter\n * `isAppearing` is supplied to indicate if the enter stage is occurring on the initial mount\n *\n * @type Function(node: HtmlElement, isAppearing: bool)\n */\n onEntering: PropTypes.func,\n\n /**\n * Callback fired after the \"entered\" status is applied. An extra parameter\n * `isAppearing` is supplied to indicate if the enter stage is occurring on the initial mount\n *\n * @type Function(node: HtmlElement, isAppearing: bool) -> void\n */\n onEntered: PropTypes.func,\n\n /**\n * Callback fired before the \"exiting\" status is applied.\n *\n * @type Function(node: HtmlElement) -> void\n */\n onExit: PropTypes.func,\n\n /**\n * Callback fired after the \"exiting\" status is applied.\n *\n * @type Function(node: HtmlElement) -> void\n */\n onExiting: PropTypes.func,\n\n /**\n * Callback fired after the \"exited\" status is applied.\n *\n * @type Function(node: HtmlElement) -> void\n */\n onExited: PropTypes.func // Name the function so it is clearer in the documentation\n\n} : {};\n\nfunction noop() {}\n\nTransition.defaultProps = {\n in: false,\n mountOnEnter: false,\n unmountOnExit: false,\n appear: false,\n enter: true,\n exit: true,\n onEnter: noop,\n onEntering: noop,\n onEntered: noop,\n onExit: noop,\n onExiting: noop,\n onExited: noop\n};\nTransition.UNMOUNTED = 0;\nTransition.EXITED = 1;\nTransition.ENTERING = 2;\nTransition.ENTERED = 3;\nTransition.EXITING = 4;\nexport default Transition;","import { Children, cloneElement, isValidElement } from 'react';\n/**\n * Given `this.props.children`, return an object mapping key to child.\n *\n * @param {*} children `this.props.children`\n * @return {object} Mapping of key to child\n */\n\nexport function getChildMapping(children, mapFn) {\n var mapper = function mapper(child) {\n return mapFn && isValidElement(child) ? mapFn(child) : child;\n };\n\n var result = Object.create(null);\n if (children) Children.map(children, function (c) {\n return c;\n }).forEach(function (child) {\n // run the map function here instead so that the key is the computed one\n result[child.key] = mapper(child);\n });\n return result;\n}\n/**\n * When you're adding or removing children some may be added or removed in the\n * same render pass. We want to show *both* since we want to simultaneously\n * animate elements in and out. This function takes a previous set of keys\n * and a new set of keys and merges them with its best guess of the correct\n * ordering. In the future we may expose some of the utilities in\n * ReactMultiChild to make this easy, but for now React itself does not\n * directly have this concept of the union of prevChildren and nextChildren\n * so we implement it here.\n *\n * @param {object} prev prev children as returned from\n * `ReactTransitionChildMapping.getChildMapping()`.\n * @param {object} next next children as returned from\n * `ReactTransitionChildMapping.getChildMapping()`.\n * @return {object} a key set that contains all keys in `prev` and all keys\n * in `next` in a reasonable order.\n */\n\nexport function mergeChildMappings(prev, next) {\n prev = prev || {};\n next = next || {};\n\n function getValueForKey(key) {\n return key in next ? next[key] : prev[key];\n } // For each key of `next`, the list of keys to insert before that key in\n // the combined list\n\n\n var nextKeysPending = Object.create(null);\n var pendingKeys = [];\n\n for (var prevKey in prev) {\n if (prevKey in next) {\n if (pendingKeys.length) {\n nextKeysPending[prevKey] = pendingKeys;\n pendingKeys = [];\n }\n } else {\n pendingKeys.push(prevKey);\n }\n }\n\n var i;\n var childMapping = {};\n\n for (var nextKey in next) {\n if (nextKeysPending[nextKey]) {\n for (i = 0; i < nextKeysPending[nextKey].length; i++) {\n var pendingNextKey = nextKeysPending[nextKey][i];\n childMapping[nextKeysPending[nextKey][i]] = getValueForKey(pendingNextKey);\n }\n }\n\n childMapping[nextKey] = getValueForKey(nextKey);\n } // Finally, add the keys which didn't appear before any key in `next`\n\n\n for (i = 0; i < pendingKeys.length; i++) {\n childMapping[pendingKeys[i]] = getValueForKey(pendingKeys[i]);\n }\n\n return childMapping;\n}\n\nfunction getProp(child, prop, props) {\n return props[prop] != null ? props[prop] : child.props[prop];\n}\n\nexport function getInitialChildMapping(props, onExited) {\n return getChildMapping(props.children, function (child) {\n return cloneElement(child, {\n onExited: onExited.bind(null, child),\n in: true,\n appear: getProp(child, 'appear', props),\n enter: getProp(child, 'enter', props),\n exit: getProp(child, 'exit', props)\n });\n });\n}\nexport function getNextChildMapping(nextProps, prevChildMapping, onExited) {\n var nextChildMapping = getChildMapping(nextProps.children);\n var children = mergeChildMappings(prevChildMapping, nextChildMapping);\n Object.keys(children).forEach(function (key) {\n var child = children[key];\n if (!isValidElement(child)) return;\n var hasPrev = key in prevChildMapping;\n var hasNext = key in nextChildMapping;\n var prevChild = prevChildMapping[key];\n var isLeaving = isValidElement(prevChild) && !prevChild.props.in; // item is new (entering)\n\n if (hasNext && (!hasPrev || isLeaving)) {\n // console.log('entering', key)\n children[key] = cloneElement(child, {\n onExited: onExited.bind(null, child),\n in: true,\n exit: getProp(child, 'exit', nextProps),\n enter: getProp(child, 'enter', nextProps)\n });\n } else if (!hasNext && hasPrev && !isLeaving) {\n // item is old (exiting)\n // console.log('leaving', key)\n children[key] = cloneElement(child, {\n in: false\n });\n } else if (hasNext && hasPrev && isValidElement(prevChild)) {\n // item hasn't changed transition states\n // copy over the last transition props;\n // console.log('unchanged', key)\n children[key] = cloneElement(child, {\n onExited: onExited.bind(null, child),\n in: prevChild.props.in,\n exit: getProp(child, 'exit', nextProps),\n enter: getProp(child, 'enter', nextProps)\n });\n }\n });\n return children;\n}","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 _assertThisInitialized from \"@babel/runtime/helpers/esm/assertThisInitialized\";\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport TransitionGroupContext from './TransitionGroupContext';\nimport { getChildMapping, getInitialChildMapping, getNextChildMapping } from './utils/ChildMapping';\n\nvar values = Object.values || function (obj) {\n return Object.keys(obj).map(function (k) {\n return obj[k];\n });\n};\n\nvar defaultProps = {\n component: 'div',\n childFactory: function childFactory(child) {\n return child;\n }\n /**\n * The `` component manages a set of transition components\n * (`` and ``) in a list. Like with the transition\n * components, `` is a state machine for managing the mounting\n * and unmounting of components over time.\n *\n * Consider the example below. As items are removed or added to the TodoList the\n * `in` prop is toggled automatically by the ``.\n *\n * Note that `` does not define any animation behavior!\n * Exactly _how_ a list item animates is up to the individual transition\n * component. This means you can mix and match animations across different list\n * items.\n */\n\n};\n\nvar TransitionGroup =\n/*#__PURE__*/\nfunction (_React$Component) {\n _inheritsLoose(TransitionGroup, _React$Component);\n\n function TransitionGroup(props, context) {\n var _this;\n\n _this = _React$Component.call(this, props, context) || this;\n\n var handleExited = _this.handleExited.bind(_assertThisInitialized(_assertThisInitialized(_this))); // Initial children should all be entering, dependent on appear\n\n\n _this.state = {\n contextValue: {\n isMounting: true\n },\n handleExited: handleExited,\n firstRender: true\n };\n return _this;\n }\n\n var _proto = TransitionGroup.prototype;\n\n _proto.componentDidMount = function componentDidMount() {\n this.mounted = true;\n this.setState({\n contextValue: {\n isMounting: false\n }\n });\n };\n\n _proto.componentWillUnmount = function componentWillUnmount() {\n this.mounted = false;\n };\n\n TransitionGroup.getDerivedStateFromProps = function getDerivedStateFromProps(nextProps, _ref) {\n var prevChildMapping = _ref.children,\n handleExited = _ref.handleExited,\n firstRender = _ref.firstRender;\n return {\n children: firstRender ? getInitialChildMapping(nextProps, handleExited) : getNextChildMapping(nextProps, prevChildMapping, handleExited),\n firstRender: false\n };\n };\n\n _proto.handleExited = function handleExited(child, node) {\n var currentChildMapping = getChildMapping(this.props.children);\n if (child.key in currentChildMapping) return;\n\n if (child.props.onExited) {\n child.props.onExited(node);\n }\n\n if (this.mounted) {\n this.setState(function (state) {\n var children = _extends({}, state.children);\n\n delete children[child.key];\n return {\n children: children\n };\n });\n }\n };\n\n _proto.render = function render() {\n var _this$props = this.props,\n Component = _this$props.component,\n childFactory = _this$props.childFactory,\n props = _objectWithoutPropertiesLoose(_this$props, [\"component\", \"childFactory\"]);\n\n var contextValue = this.state.contextValue;\n var children = values(this.state.children).map(childFactory);\n delete props.appear;\n delete props.enter;\n delete props.exit;\n\n if (Component === null) {\n return React.createElement(TransitionGroupContext.Provider, {\n value: contextValue\n }, children);\n }\n\n return React.createElement(TransitionGroupContext.Provider, {\n value: contextValue\n }, React.createElement(Component, props, children));\n };\n\n return TransitionGroup;\n}(React.Component);\n\nTransitionGroup.propTypes = process.env.NODE_ENV !== \"production\" ? {\n /**\n * `` renders a `
` by default. You can change this\n * behavior by providing a `component` prop.\n * If you use React v16+ and would like to avoid a wrapping `
` element\n * you can pass in `component={null}`. This is useful if the wrapping div\n * borks your css styles.\n */\n component: PropTypes.any,\n\n /**\n * A set of `` components, that are toggled `in` and out as they\n * leave. the `` will inject specific transition props, so\n * remember to spread them through if you are wrapping the `` as\n * with our `` example.\n *\n * While this component is meant for multiple `Transition` or `CSSTransition`\n * children, sometimes you may want to have a single transition child with\n * content that you want to be transitioned out and in when you change it\n * (e.g. routes, images etc.) In that case you can change the `key` prop of\n * the transition child as you change its content, this will cause\n * `TransitionGroup` to transition the child out and back in.\n */\n children: PropTypes.node,\n\n /**\n * A convenience prop that enables or disables appear animations\n * for all children. Note that specifying this will override any defaults set\n * on individual children Transitions.\n */\n appear: PropTypes.bool,\n\n /**\n * A convenience prop that enables or disables enter animations\n * for all children. Note that specifying this will override any defaults set\n * on individual children Transitions.\n */\n enter: PropTypes.bool,\n\n /**\n * A convenience prop that enables or disables exit animations\n * for all children. Note that specifying this will override any defaults set\n * on individual children Transitions.\n */\n exit: PropTypes.bool,\n\n /**\n * You may need to apply reactive updates to a child as it is exiting.\n * This is generally done by using `cloneElement` however in the case of an exiting\n * child the element has already been removed and not accessible to the consumer.\n *\n * If you do need to update a child as it leaves you can provide a `childFactory`\n * to wrap every child, even the ones that are leaving.\n *\n * @type Function(child: ReactElement) -> ReactElement\n */\n childFactory: PropTypes.func\n} : {};\nTransitionGroup.defaultProps = defaultProps;\nexport default TransitionGroup;","import _extends from '@babel/runtime/helpers/esm/extends';\nimport _objectWithoutPropertiesLoose from '@babel/runtime/helpers/esm/objectWithoutPropertiesLoose';\nimport _inheritsLoose from '@babel/runtime/helpers/esm/inheritsLoose';\nimport React, { Component, isValidElement, cloneElement } from 'react';\nimport PropTypes from 'prop-types';\nimport cx from 'classnames';\nimport { Transition, TransitionGroup } from 'react-transition-group';\nimport { render } from 'react-dom';\n\nvar POSITION = {\n TOP_LEFT: 'top-left',\n TOP_RIGHT: 'top-right',\n TOP_CENTER: 'top-center',\n BOTTOM_LEFT: 'bottom-left',\n BOTTOM_RIGHT: 'bottom-right',\n BOTTOM_CENTER: 'bottom-center'\n};\nvar TYPE = {\n INFO: 'info',\n SUCCESS: 'success',\n WARNING: 'warning',\n ERROR: 'error',\n DEFAULT: 'default'\n};\nvar ACTION = {\n SHOW: 0,\n CLEAR: 1,\n DID_MOUNT: 2,\n WILL_UNMOUNT: 3,\n ON_CHANGE: 4\n};\nvar NOOP = function NOOP() {};\nvar RT_NAMESPACE = 'Toastify';\n\nfunction isValidDelay(val) {\n return typeof val === 'number' && !isNaN(val) && val > 0;\n}\nfunction objectValues(obj) {\n return Object.keys(obj).map(function (key) {\n return obj[key];\n });\n}\nvar canUseDom = !!(typeof window !== 'undefined' && window.document && window.document.createElement);\n\nfunction withRequired(fn) {\n fn.isRequired = function (props, propName, componentName) {\n var prop = props[propName];\n\n if (typeof prop === 'undefined') {\n return new Error(\"The prop \" + propName + \" is marked as required in \\n \" + componentName + \", but its value is undefined.\");\n }\n\n fn(props, propName, componentName);\n };\n\n return fn;\n}\n\nvar falseOrDelay = withRequired(function (props, propName, componentName) {\n var prop = props[propName];\n\n if (prop !== false && !isValidDelay(prop)) {\n return new Error(componentName + \" expect \" + propName + \" \\n to be a valid Number > 0 or equal to false. \" + prop + \" given.\");\n }\n\n return null;\n});\n\nvar eventManager = {\n list: new Map(),\n emitQueue: new Map(),\n on: function on(event, callback) {\n this.list.has(event) || this.list.set(event, []);\n this.list.get(event).push(callback);\n return this;\n },\n off: function off(event) {\n this.list.delete(event);\n return this;\n },\n cancelEmit: function cancelEmit(event) {\n var timers = this.emitQueue.get(event);\n\n if (timers) {\n timers.forEach(function (timer) {\n return clearTimeout(timer);\n });\n this.emitQueue.delete(event);\n }\n\n return this;\n },\n\n /**\n * Enqueue the event at the end of the call stack\n * Doing so let the user call toast as follow:\n * toast('1')\n * toast('2')\n * toast('3')\n * Without setTimemout the code above will not work\n */\n emit: function emit(event) {\n var _this = this;\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 this.list.has(event) && this.list.get(event).forEach(function (callback) {\n var timer = setTimeout(function () {\n callback.apply(void 0, args);\n }, 0);\n _this.emitQueue.has(event) || _this.emitQueue.set(event, []);\n\n _this.emitQueue.get(event).push(timer);\n });\n }\n};\n\nfunction cssTransition(_ref) {\n var enter = _ref.enter,\n exit = _ref.exit,\n _ref$duration = _ref.duration,\n duration = _ref$duration === void 0 ? 750 : _ref$duration,\n _ref$appendPosition = _ref.appendPosition,\n appendPosition = _ref$appendPosition === void 0 ? false : _ref$appendPosition;\n return function Animation(_ref2) {\n var children = _ref2.children,\n position = _ref2.position,\n preventExitTransition = _ref2.preventExitTransition,\n props = _objectWithoutPropertiesLoose(_ref2, [\"children\", \"position\", \"preventExitTransition\"]);\n\n var enterClassName = appendPosition ? enter + \"--\" + position : enter;\n var exitClassName = appendPosition ? exit + \"--\" + position : exit;\n var enterDuration, exitDuration;\n\n if (Array.isArray(duration) && duration.length === 2) {\n enterDuration = duration[0];\n exitDuration = duration[1];\n } else {\n enterDuration = exitDuration = duration;\n }\n\n var onEnter = function onEnter(node) {\n node.classList.add(enterClassName);\n node.style.animationFillMode = 'forwards';\n node.style.animationDuration = enterDuration * 0.001 + \"s\";\n };\n\n var onEntered = function onEntered(node) {\n node.classList.remove(enterClassName);\n node.style.cssText = '';\n };\n\n var onExit = function onExit(node) {\n node.classList.add(exitClassName);\n node.style.animationFillMode = 'forwards';\n node.style.animationDuration = exitDuration * 0.001 + \"s\";\n };\n\n return React.createElement(Transition, _extends({}, props, {\n timeout: preventExitTransition ? 0 : {\n enter: enterDuration,\n exit: exitDuration\n },\n onEnter: onEnter,\n onEntered: onEntered,\n onExit: preventExitTransition ? NOOP : onExit\n }), children);\n };\n}\n\nfunction ProgressBar(_ref) {\n var _cx, _animationEvent;\n\n var delay = _ref.delay,\n isRunning = _ref.isRunning,\n closeToast = _ref.closeToast,\n type = _ref.type,\n hide = _ref.hide,\n className = _ref.className,\n userStyle = _ref.style,\n controlledProgress = _ref.controlledProgress,\n progress = _ref.progress,\n rtl = _ref.rtl;\n\n var style = _extends({}, userStyle, {\n animationDuration: delay + \"ms\",\n animationPlayState: isRunning ? 'running' : 'paused',\n opacity: hide ? 0 : 1,\n transform: controlledProgress ? \"scaleX(\" + progress + \")\" : null\n });\n\n var classNames = cx(RT_NAMESPACE + \"__progress-bar\", controlledProgress ? RT_NAMESPACE + \"__progress-bar--controlled\" : RT_NAMESPACE + \"__progress-bar--animated\", RT_NAMESPACE + \"__progress-bar--\" + type, (_cx = {}, _cx[RT_NAMESPACE + \"__progress-bar--rtl\"] = rtl, _cx), className);\n var animationEvent = (_animationEvent = {}, _animationEvent[controlledProgress && progress >= 1 ? 'onTransitionEnd' : 'onAnimationEnd'] = controlledProgress && progress < 1 ? null : closeToast, _animationEvent);\n return React.createElement(\"div\", _extends({\n className: classNames,\n style: style\n }, animationEvent));\n}\n\nProgressBar.propTypes = {\n /**\n * The animation delay which determine when to close the toast\n */\n delay: falseOrDelay.isRequired,\n\n /**\n * Whether or not the animation is running or paused\n */\n isRunning: PropTypes.bool.isRequired,\n\n /**\n * Func to close the current toast\n */\n closeToast: PropTypes.func.isRequired,\n\n /**\n * Support rtl content\n */\n rtl: PropTypes.bool.isRequired,\n\n /**\n * Optional type : info, success ...\n */\n type: PropTypes.string,\n\n /**\n * Hide or not the progress bar\n */\n hide: PropTypes.bool,\n\n /**\n * Optionnal className\n */\n className: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),\n\n /**\n * Controlled progress value\n */\n progress: PropTypes.number,\n\n /**\n * Tell wether or not controlled progress bar is used\n */\n controlledProgress: PropTypes.bool\n};\nProgressBar.defaultProps = {\n type: TYPE.DEFAULT,\n hide: false\n};\n\nfunction getX(e) {\n return e.targetTouches && e.targetTouches.length >= 1 ? e.targetTouches[0].clientX : e.clientX;\n}\n\nfunction getY(e) {\n return e.targetTouches && e.targetTouches.length >= 1 ? e.targetTouches[0].clientY : e.clientY;\n}\n\nvar iLoveInternetExplorer = canUseDom && /(msie|trident)/i.test(navigator.userAgent);\n\nvar Toast =\n/*#__PURE__*/\nfunction (_Component) {\n _inheritsLoose(Toast, _Component);\n\n function Toast() {\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 isRunning: true,\n preventExitTransition: false\n };\n _this.flag = {\n canCloseOnClick: true,\n canDrag: false\n };\n _this.drag = {\n start: 0,\n x: 0,\n y: 0,\n deltaX: 0,\n removalDistance: 0\n };\n _this.boundingRect = null;\n _this.ref = null;\n\n _this.pauseToast = function () {\n if (_this.props.autoClose) {\n _this.setState({\n isRunning: false\n });\n }\n };\n\n _this.playToast = function () {\n if (_this.props.autoClose) {\n _this.setState({\n isRunning: true\n });\n }\n };\n\n _this.onDragStart = function (e) {\n _this.flag.canCloseOnClick = true;\n _this.flag.canDrag = true;\n _this.boundingRect = _this.ref.getBoundingClientRect();\n _this.ref.style.transition = '';\n _this.drag.start = _this.drag.x = getX(e.nativeEvent);\n _this.drag.removalDistance = _this.ref.offsetWidth * (_this.props.draggablePercent / 100);\n };\n\n _this.onDragMove = function (e) {\n if (_this.flag.canDrag) {\n if (_this.state.isRunning) {\n _this.pauseToast();\n }\n\n _this.drag.x = getX(e);\n _this.drag.deltaX = _this.drag.x - _this.drag.start;\n _this.drag.y = getY(e); // prevent false positif during a toast click\n\n _this.drag.start !== _this.drag.x && (_this.flag.canCloseOnClick = false);\n _this.ref.style.transform = \"translateX(\" + _this.drag.deltaX + \"px)\";\n _this.ref.style.opacity = 1 - Math.abs(_this.drag.deltaX / _this.drag.removalDistance);\n }\n };\n\n _this.onDragEnd = function (e) {\n if (_this.flag.canDrag) {\n _this.flag.canDrag = false;\n\n if (Math.abs(_this.drag.deltaX) > _this.drag.removalDistance) {\n _this.setState({\n preventExitTransition: true\n }, _this.props.closeToast);\n\n return;\n }\n\n _this.ref.style.transition = 'transform 0.2s, opacity 0.2s';\n _this.ref.style.transform = 'translateX(0)';\n _this.ref.style.opacity = 1;\n }\n };\n\n _this.onDragTransitionEnd = function () {\n if (_this.boundingRect) {\n var _this$boundingRect = _this.boundingRect,\n top = _this$boundingRect.top,\n bottom = _this$boundingRect.bottom,\n left = _this$boundingRect.left,\n right = _this$boundingRect.right;\n\n if (_this.props.pauseOnHover && _this.drag.x >= left && _this.drag.x <= right && _this.drag.y >= top && _this.drag.y <= bottom) {\n _this.pauseToast();\n } else {\n _this.playToast();\n }\n }\n };\n\n _this.onExitTransitionEnd = function () {\n if (iLoveInternetExplorer) {\n _this.props.onExited();\n\n return;\n }\n\n var height = _this.ref.scrollHeight;\n var style = _this.ref.style;\n requestAnimationFrame(function () {\n style.minHeight = 'initial';\n style.height = height + 'px';\n style.transition = 'all 0.4s ';\n requestAnimationFrame(function () {\n style.height = 0;\n style.padding = 0;\n style.margin = 0;\n });\n setTimeout(function () {\n return _this.props.onExited();\n }, 400);\n });\n };\n\n return _this;\n }\n\n var _proto = Toast.prototype;\n\n _proto.componentDidMount = function componentDidMount() {\n this.props.onOpen(this.props.children.props);\n\n if (this.props.draggable) {\n this.bindDragEvents();\n } // Maybe I could bind the event in the ToastContainer and rely on delegation\n\n\n if (this.props.pauseOnFocusLoss) {\n this.bindFocusEvents();\n }\n };\n\n _proto.componentDidUpdate = function componentDidUpdate(prevProps) {\n if (prevProps.draggable !== this.props.draggable) {\n if (this.props.draggable) {\n this.bindDragEvents();\n } else {\n this.unbindDragEvents();\n }\n }\n\n if (prevProps.pauseOnFocusLoss !== this.props.pauseOnFocusLoss) {\n if (this.props.pauseOnFocusLoss) {\n this.bindFocusEvents();\n } else {\n this.unbindFocusEvents();\n }\n }\n };\n\n _proto.componentWillUnmount = function componentWillUnmount() {\n this.props.onClose(this.props.children.props);\n\n if (this.props.draggable) {\n this.unbindDragEvents();\n }\n\n if (this.props.pauseOnFocusLoss) {\n this.unbindFocusEvents();\n }\n };\n\n _proto.bindFocusEvents = function bindFocusEvents() {\n window.addEventListener('focus', this.playToast);\n window.addEventListener('blur', this.pauseToast);\n };\n\n _proto.unbindFocusEvents = function unbindFocusEvents() {\n window.removeEventListener('focus', this.playToast);\n window.removeEventListener('blur', this.pauseToast);\n };\n\n _proto.bindDragEvents = function bindDragEvents() {\n document.addEventListener('mousemove', this.onDragMove);\n document.addEventListener('mouseup', this.onDragEnd);\n document.addEventListener('touchmove', this.onDragMove);\n document.addEventListener('touchend', this.onDragEnd);\n };\n\n _proto.unbindDragEvents = function unbindDragEvents() {\n document.removeEventListener('mousemove', this.onDragMove);\n document.removeEventListener('mouseup', this.onDragEnd);\n document.removeEventListener('touchmove', this.onDragMove);\n document.removeEventListener('touchend', this.onDragEnd);\n };\n\n _proto.render = function render() {\n var _cx,\n _this2 = this;\n\n var _this$props = this.props,\n closeButton = _this$props.closeButton,\n children = _this$props.children,\n autoClose = _this$props.autoClose,\n pauseOnHover = _this$props.pauseOnHover,\n onClick = _this$props.onClick,\n closeOnClick = _this$props.closeOnClick,\n type = _this$props.type,\n hideProgressBar = _this$props.hideProgressBar,\n closeToast = _this$props.closeToast,\n Transition = _this$props.transition,\n position = _this$props.position,\n className = _this$props.className,\n bodyClassName = _this$props.bodyClassName,\n progressClassName = _this$props.progressClassName,\n progressStyle = _this$props.progressStyle,\n updateId = _this$props.updateId,\n role = _this$props.role,\n progress = _this$props.progress,\n rtl = _this$props.rtl;\n var toastProps = {\n className: cx(RT_NAMESPACE + \"__toast\", RT_NAMESPACE + \"__toast--\" + type, (_cx = {}, _cx[RT_NAMESPACE + \"__toast--rtl\"] = rtl, _cx), className)\n };\n\n if (autoClose && pauseOnHover) {\n toastProps.onMouseEnter = this.pauseToast;\n toastProps.onMouseLeave = this.playToast;\n } // prevent toast from closing when user drags the toast\n\n\n if (closeOnClick) {\n toastProps.onClick = function (e) {\n onClick && onClick(e);\n _this2.flag.canCloseOnClick && closeToast();\n };\n }\n\n var controlledProgress = parseFloat(progress) === progress;\n return React.createElement(Transition, {\n in: this.props.in,\n appear: true,\n onExited: this.onExitTransitionEnd,\n position: position,\n preventExitTransition: this.state.preventExitTransition\n }, React.createElement(\"div\", _extends({\n onClick: onClick\n }, toastProps, {\n ref: function ref(_ref) {\n return _this2.ref = _ref;\n },\n onMouseDown: this.onDragStart,\n onTouchStart: this.onDragStart,\n onMouseUp: this.onDragTransitionEnd,\n onTouchEnd: this.onDragTransitionEnd\n }), React.createElement(\"div\", _extends({}, this.props.in && {\n role: role\n }, {\n className: cx(RT_NAMESPACE + \"__toast-body\", bodyClassName)\n }), children), closeButton && closeButton, (autoClose || controlledProgress) && React.createElement(ProgressBar, _extends({}, updateId && !controlledProgress ? {\n key: \"pb-\" + updateId\n } : {}, {\n rtl: rtl,\n delay: autoClose,\n isRunning: this.state.isRunning,\n closeToast: closeToast,\n hide: hideProgressBar,\n type: type,\n style: progressStyle,\n className: progressClassName,\n controlledProgress: controlledProgress,\n progress: progress\n }))));\n };\n\n return Toast;\n}(Component);\n\nToast.propTypes = {\n closeButton: PropTypes.oneOfType([PropTypes.node, PropTypes.bool]).isRequired,\n autoClose: falseOrDelay.isRequired,\n children: PropTypes.node.isRequired,\n closeToast: PropTypes.func.isRequired,\n position: PropTypes.oneOf(objectValues(POSITION)).isRequired,\n pauseOnHover: PropTypes.bool.isRequired,\n pauseOnFocusLoss: PropTypes.bool.isRequired,\n closeOnClick: PropTypes.bool.isRequired,\n transition: PropTypes.func.isRequired,\n rtl: PropTypes.bool.isRequired,\n hideProgressBar: PropTypes.bool.isRequired,\n draggable: PropTypes.bool.isRequired,\n draggablePercent: PropTypes.number.isRequired,\n in: PropTypes.bool,\n onExited: PropTypes.func,\n onOpen: PropTypes.func,\n onClose: PropTypes.func,\n type: PropTypes.oneOf(objectValues(TYPE)),\n className: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),\n bodyClassName: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),\n progressClassName: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),\n progressStyle: PropTypes.object,\n progress: PropTypes.number,\n updateId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),\n ariaLabel: PropTypes.string,\n containerId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),\n role: PropTypes.string\n};\nToast.defaultProps = {\n type: TYPE.DEFAULT,\n in: true,\n onOpen: NOOP,\n onClose: NOOP,\n className: null,\n bodyClassName: null,\n progressClassName: null,\n updateId: null\n};\n\nfunction CloseButton(_ref) {\n var closeToast = _ref.closeToast,\n type = _ref.type,\n ariaLabel = _ref.ariaLabel;\n return React.createElement(\"button\", {\n className: RT_NAMESPACE + \"__close-button \" + RT_NAMESPACE + \"__close-button--\" + type,\n type: \"button\",\n onClick: function onClick(e) {\n e.stopPropagation();\n closeToast(e);\n },\n \"aria-label\": ariaLabel\n }, \"\\u2716\\uFE0E\");\n}\n\nCloseButton.propTypes = {\n closeToast: PropTypes.func,\n arialLabel: PropTypes.string\n};\nCloseButton.defaultProps = {\n ariaLabel: 'close'\n};\n\nvar Bounce = cssTransition({\n enter: RT_NAMESPACE + \"__bounce-enter\",\n exit: RT_NAMESPACE + \"__bounce-exit\",\n appendPosition: true\n});\nvar Slide = cssTransition({\n enter: RT_NAMESPACE + \"__slide-enter\",\n exit: RT_NAMESPACE + \"__slide-exit\",\n duration: [450, 750],\n appendPosition: true\n});\nvar Zoom = cssTransition({\n enter: RT_NAMESPACE + \"__zoom-enter\",\n exit: RT_NAMESPACE + \"__zoom-exit\"\n});\nvar Flip = cssTransition({\n enter: RT_NAMESPACE + \"__flip-enter\",\n exit: RT_NAMESPACE + \"__flip-exit\"\n});\n\nvar ToastContainer =\n/*#__PURE__*/\nfunction (_Component) {\n _inheritsLoose(ToastContainer, _Component);\n\n function ToastContainer() {\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 toast: []\n };\n _this.toastKey = 1;\n _this.collection = {};\n\n _this.isToastActive = function (id) {\n return _this.state.toast.indexOf(id) !== -1;\n };\n\n return _this;\n }\n\n var _proto = ToastContainer.prototype;\n\n _proto.componentDidMount = function componentDidMount() {\n var _this2 = this;\n\n eventManager.cancelEmit(ACTION.WILL_UNMOUNT).on(ACTION.SHOW, function (content, options) {\n return _this2.ref ? _this2.buildToast(content, options) : null;\n }).on(ACTION.CLEAR, function (id) {\n return !_this2.ref ? null : id == null ? _this2.clear() : _this2.removeToast(id);\n }).emit(ACTION.DID_MOUNT, this);\n };\n\n _proto.componentWillUnmount = function componentWillUnmount() {\n eventManager.emit(ACTION.WILL_UNMOUNT, this);\n };\n\n _proto.removeToast = function removeToast(id) {\n this.setState({\n toast: this.state.toast.filter(function (v) {\n return v !== id;\n })\n }, this.dispatchChange);\n };\n\n _proto.dispatchChange = function dispatchChange() {\n eventManager.emit(ACTION.ON_CHANGE, this.state.toast.length, this.props.containerId);\n };\n\n _proto.makeCloseButton = function makeCloseButton(toastClose, toastId, type) {\n var _this3 = this;\n\n var closeButton = this.props.closeButton;\n\n if (isValidElement(toastClose) || toastClose === false) {\n closeButton = toastClose;\n } else if (toastClose === true) {\n closeButton = this.props.closeButton && typeof this.props.closeButton !== 'boolean' ? this.props.closeButton : React.createElement(CloseButton, null);\n }\n\n return closeButton === false ? false : cloneElement(closeButton, {\n closeToast: function closeToast() {\n return _this3.removeToast(toastId);\n },\n type: type\n });\n };\n\n _proto.getAutoCloseDelay = function getAutoCloseDelay(toastAutoClose) {\n return toastAutoClose === false || isValidDelay(toastAutoClose) ? toastAutoClose : this.props.autoClose;\n };\n\n _proto.canBeRendered = function canBeRendered(content) {\n return isValidElement(content) || typeof content === 'string' || typeof content === 'number' || typeof content === 'function';\n };\n\n _proto.parseClassName = function parseClassName(prop) {\n if (typeof prop === 'string') {\n return prop;\n } else if (prop !== null && typeof prop === 'object' && 'toString' in prop) {\n return prop.toString();\n }\n\n return null;\n };\n\n _proto.belongToContainer = function belongToContainer(_ref) {\n var containerId = _ref.containerId;\n return containerId === this.props.containerId;\n };\n\n _proto.buildToast = function buildToast(content, _ref2) {\n var _this4 = this;\n\n var delay = _ref2.delay,\n options = _objectWithoutPropertiesLoose(_ref2, [\"delay\"]);\n\n if (!this.canBeRendered(content)) {\n throw new Error(\"The element you provided cannot be rendered. You provided an element of type \" + typeof content);\n }\n\n var toastId = options.toastId,\n updateId = options.updateId; // Check for multi-container and also for duplicate toastId\n // Maybe it would be better to extract it\n\n if (this.props.enableMultiContainer && !this.belongToContainer(options) || this.isToastActive(toastId) && updateId == null) {\n return;\n }\n\n var closeToast = function closeToast() {\n return _this4.removeToast(toastId);\n };\n\n var toastOptions = {\n id: toastId,\n // ⚠️ if no options.key, this.toastKey - 1 is assigned\n key: options.key || this.toastKey++,\n type: options.type,\n closeToast: closeToast,\n updateId: options.updateId,\n rtl: this.props.rtl,\n position: options.position || this.props.position,\n transition: options.transition || this.props.transition,\n className: this.parseClassName(options.className || this.props.toastClassName),\n bodyClassName: this.parseClassName(options.bodyClassName || this.props.bodyClassName),\n onClick: options.onClick || this.props.onClick,\n closeButton: this.makeCloseButton(options.closeButton, toastId, options.type),\n pauseOnHover: typeof options.pauseOnHover === 'boolean' ? options.pauseOnHover : this.props.pauseOnHover,\n pauseOnFocusLoss: typeof options.pauseOnFocusLoss === 'boolean' ? options.pauseOnFocusLoss : this.props.pauseOnFocusLoss,\n draggable: typeof options.draggable === 'boolean' ? options.draggable : this.props.draggable,\n draggablePercent: typeof options.draggablePercent === 'number' && !isNaN(options.draggablePercent) ? options.draggablePercent : this.props.draggablePercent,\n closeOnClick: typeof options.closeOnClick === 'boolean' ? options.closeOnClick : this.props.closeOnClick,\n progressClassName: this.parseClassName(options.progressClassName || this.props.progressClassName),\n progressStyle: this.props.progressStyle,\n autoClose: this.getAutoCloseDelay(options.autoClose),\n hideProgressBar: typeof options.hideProgressBar === 'boolean' ? options.hideProgressBar : this.props.hideProgressBar,\n progress: parseFloat(options.progress),\n role: typeof options.role === 'string' ? options.role : this.props.role\n };\n typeof options.onOpen === 'function' && (toastOptions.onOpen = options.onOpen);\n typeof options.onClose === 'function' && (toastOptions.onClose = options.onClose); // add closeToast function to react component only\n\n if (isValidElement(content) && typeof content.type !== 'string' && typeof content.type !== 'number') {\n content = cloneElement(content, {\n closeToast: closeToast\n });\n } else if (typeof content === 'function') {\n content = content({\n closeToast: closeToast\n });\n }\n\n if (isValidDelay(delay)) {\n setTimeout(function () {\n _this4.appendToast(toastOptions, content, options.staleToastId);\n }, delay);\n } else {\n this.appendToast(toastOptions, content, options.staleToastId);\n }\n };\n\n _proto.appendToast = function appendToast(options, content, staleToastId) {\n var _extends2;\n\n var id = options.id,\n updateId = options.updateId;\n this.collection = _extends({}, this.collection, (_extends2 = {}, _extends2[id] = {\n options: options,\n content: content,\n position: options.position\n }, _extends2));\n this.setState({\n toast: (updateId ? [].concat(this.state.toast) : [].concat(this.state.toast, [id])).filter(function (id) {\n return id !== staleToastId;\n })\n }, this.dispatchChange);\n };\n\n _proto.clear = function clear() {\n this.setState({\n toast: []\n });\n };\n\n _proto.renderToast = function renderToast() {\n var _this5 = this;\n\n var toastToRender = {};\n var _this$props = this.props,\n className = _this$props.className,\n style = _this$props.style,\n newestOnTop = _this$props.newestOnTop;\n var collection = newestOnTop ? Object.keys(this.collection).reverse() : Object.keys(this.collection); // group toast by position\n\n collection.forEach(function (toastId) {\n var _this5$collection$toa = _this5.collection[toastId],\n position = _this5$collection$toa.position,\n options = _this5$collection$toa.options,\n content = _this5$collection$toa.content;\n toastToRender[position] || (toastToRender[position] = []);\n\n if (_this5.state.toast.indexOf(options.id) !== -1) {\n toastToRender[position].push(React.createElement(Toast, _extends({}, options, {\n isDocumentHidden: _this5.state.isDocumentHidden,\n key: \"toast-\" + options.key\n }), content));\n } else {\n toastToRender[position].push(null);\n delete _this5.collection[toastId];\n }\n });\n return Object.keys(toastToRender).map(function (position) {\n var _cx;\n\n var disablePointer = toastToRender[position].length === 1 && toastToRender[position][0] === null;\n var props = {\n className: cx(RT_NAMESPACE + \"__toast-container\", RT_NAMESPACE + \"__toast-container--\" + position, (_cx = {}, _cx[RT_NAMESPACE + \"__toast-container--rtl\"] = _this5.props.rtl, _cx), _this5.parseClassName(className)),\n style: disablePointer ? _extends({}, style, {\n pointerEvents: 'none'\n }) : _extends({}, style)\n };\n return React.createElement(TransitionGroup, _extends({}, props, {\n key: \"container-\" + position\n }), toastToRender[position]);\n });\n };\n\n _proto.render = function render() {\n var _this6 = this;\n\n return React.createElement(\"div\", {\n ref: function ref(node) {\n return _this6.ref = node;\n },\n className: \"\" + RT_NAMESPACE\n }, this.renderToast());\n };\n\n return ToastContainer;\n}(Component);\n\nToastContainer.propTypes = {\n /**\n * Set toast position\n */\n position: PropTypes.oneOf(objectValues(POSITION)),\n\n /**\n * Disable or set autoClose delay\n */\n autoClose: falseOrDelay,\n\n /**\n * Disable or set a custom react element for the close button\n */\n closeButton: PropTypes.oneOfType([PropTypes.node, PropTypes.bool]),\n\n /**\n * Hide or not progress bar when autoClose is enabled\n */\n hideProgressBar: PropTypes.bool,\n\n /**\n * Pause toast duration on hover\n */\n pauseOnHover: PropTypes.bool,\n\n /**\n * Dismiss toast on click\n */\n closeOnClick: PropTypes.bool,\n\n /**\n * Newest on top\n */\n newestOnTop: PropTypes.bool,\n\n /**\n * An optional className\n */\n className: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),\n\n /**\n * An optional style\n */\n style: PropTypes.object,\n\n /**\n * An optional className for the toast\n */\n toastClassName: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),\n\n /**\n * An optional className for the toast body\n */\n bodyClassName: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),\n\n /**\n * An optional className for the toast progress bar\n */\n progressClassName: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),\n\n /**\n * An optional style for the toast progress bar\n */\n progressStyle: PropTypes.object,\n\n /**\n * Define enter and exit transition using react-transition-group\n */\n transition: PropTypes.func,\n\n /**\n * Support rtl display\n */\n rtl: PropTypes.bool,\n\n /**\n * Allow toast to be draggable\n */\n draggable: PropTypes.bool,\n\n /**\n * The percentage of the toast's width it takes for a drag to dismiss a toast\n */\n draggablePercent: PropTypes.number,\n\n /**\n * Pause the toast on focus loss\n */\n pauseOnFocusLoss: PropTypes.bool,\n\n /**\n * Show the toast only if it includes containerId and it's the same as containerId\n */\n enableMultiContainer: PropTypes.bool,\n\n /**\n * Set id to handle multiple container\n */\n containerId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),\n\n /**\n * Set role attribute for the toast body\n */\n role: PropTypes.string,\n\n /**\n * Fired when clicking inside toaster\n */\n onClick: PropTypes.func\n};\nToastContainer.defaultProps = {\n position: POSITION.TOP_RIGHT,\n transition: Bounce,\n rtl: false,\n autoClose: 5000,\n hideProgressBar: false,\n closeButton: React.createElement(CloseButton, null),\n pauseOnHover: true,\n pauseOnFocusLoss: true,\n closeOnClick: true,\n newestOnTop: false,\n draggable: true,\n draggablePercent: 80,\n className: null,\n style: null,\n toastClassName: null,\n bodyClassName: null,\n progressClassName: null,\n progressStyle: null,\n role: 'alert'\n};\n\nvar containers = new Map();\nvar latestInstance = null;\nvar containerDomNode = null;\nvar containerConfig = {};\nvar queue = [];\nvar lazy = false;\n/**\n * Check whether any container is currently mounted in the DOM\n */\n\nfunction isAnyContainerMounted() {\n return containers.size > 0;\n}\n/**\n * Get the container by id. Returns the last container declared when no id is given.\n */\n\n\nfunction getContainer(containerId) {\n if (!isAnyContainerMounted()) return null;\n if (!containerId) return containers.get(latestInstance);\n return containers.get(containerId);\n}\n/**\n * Get the toast by id, given it's in the DOM, otherwise returns null\n */\n\n\nfunction getToast(toastId, _ref) {\n var containerId = _ref.containerId;\n var container = getContainer(containerId);\n if (!container) return null;\n var toast = container.collection[toastId];\n if (typeof toast === 'undefined') return null;\n return toast;\n}\n/**\n * Merge provided options with the defaults settings and generate the toastId\n */\n\n\nfunction mergeOptions(options, type) {\n return _extends({}, options, {\n type: type,\n toastId: getToastId(options)\n });\n}\n/**\n * Generate a random toastId\n */\n\n\nfunction generateToastId() {\n return (Math.random().toString(36) + Date.now().toString(36)).substr(2, 10);\n}\n/**\n * Generate a toastId or use the one provided\n */\n\n\nfunction getToastId(options) {\n if (options && (typeof options.toastId === 'string' || typeof options.toastId === 'number' && !isNaN(options.toastId))) {\n return options.toastId;\n }\n\n return generateToastId();\n}\n/**\n * If the container is not mounted, the toast is enqueued and\n * the container lazy mounted\n */\n\n\nfunction dispatchToast(content, options) {\n if (isAnyContainerMounted()) {\n eventManager.emit(ACTION.SHOW, content, options);\n } else {\n queue.push({\n action: ACTION.SHOW,\n content: content,\n options: options\n });\n\n if (lazy && canUseDom) {\n lazy = false;\n containerDomNode = document.createElement('div');\n document.body.appendChild(containerDomNode);\n render(React.createElement(ToastContainer, containerConfig), containerDomNode);\n }\n }\n\n return options.toastId;\n}\n\nvar toast = function toast(content, options) {\n return dispatchToast(content, mergeOptions(options, options && options.type || TYPE.DEFAULT));\n};\n/**\n * For each available type create a shortcut\n */\n\n\nvar _loop = function _loop(t) {\n if (TYPE[t] !== TYPE.DEFAULT) {\n toast[TYPE[t].toLowerCase()] = function (content, options) {\n return dispatchToast(content, mergeOptions(options, options && options.type || TYPE[t]));\n };\n }\n};\n\nfor (var t in TYPE) {\n _loop(t);\n}\n/**\n * Maybe I should remove warning in favor of warn, I don't know\n */\n\n\ntoast.warn = toast.warning;\n/**\n * Remove toast programmaticaly\n */\n\ntoast.dismiss = function (id) {\n if (id === void 0) {\n id = null;\n }\n\n return isAnyContainerMounted() && eventManager.emit(ACTION.CLEAR, id);\n};\n/**\n * return true if one container is displaying the toast\n */\n\n\ntoast.isActive = function (id) {\n var isToastActive = false;\n\n if (containers.size > 0) {\n containers.forEach(function (container) {\n if (container.isToastActive(id)) {\n isToastActive = true;\n }\n });\n }\n\n return isToastActive;\n};\n\ntoast.update = function (toastId, options) {\n if (options === void 0) {\n options = {};\n }\n\n // if you call toast and toast.update directly nothing will be displayed\n // this is why I defered the update\n setTimeout(function () {\n var toast = getToast(toastId, options);\n\n if (toast) {\n var oldOptions = toast.options,\n oldContent = toast.content;\n\n var nextOptions = _extends({}, oldOptions, {}, options, {\n toastId: options.toastId || toastId\n });\n\n if (!options.toastId || options.toastId === toastId) {\n nextOptions.updateId = generateToastId();\n } else {\n nextOptions.staleToastId = toastId;\n }\n\n var content = typeof nextOptions.render !== 'undefined' ? nextOptions.render : oldContent;\n delete nextOptions.render;\n dispatchToast(content, nextOptions);\n }\n }, 0);\n};\n/**\n * Used for controlled progress bar.\n */\n\n\ntoast.done = function (id) {\n toast.update(id, {\n progress: 1\n });\n};\n/**\n * Track changes. The callback get the number of toast displayed\n */\n\n\ntoast.onChange = function (callback) {\n if (typeof callback === 'function') {\n eventManager.on(ACTION.ON_CHANGE, callback);\n }\n};\n/**\n * Configure the ToastContainer when lazy mounted\n */\n\n\ntoast.configure = function (config) {\n lazy = true;\n containerConfig = config;\n};\n\ntoast.POSITION = POSITION;\ntoast.TYPE = TYPE;\n/**\n * Wait until the ToastContainer is mounted to dispatch the toast\n * and attach isActive method\n */\n\neventManager.on(ACTION.DID_MOUNT, function (containerInstance) {\n latestInstance = containerInstance.props.containerId || containerInstance;\n containers.set(latestInstance, containerInstance);\n queue.forEach(function (item) {\n eventManager.emit(item.action, item.content, item.options);\n });\n queue = [];\n}).on(ACTION.WILL_UNMOUNT, function (containerInstance) {\n if (containerInstance) containers.delete(containerInstance.props.containerId || containerInstance);else containers.clear();\n\n if (containers.size === 0) {\n eventManager.off(ACTION.SHOW).off(ACTION.CLEAR);\n }\n\n if (canUseDom && containerDomNode) {\n document.body.removeChild(containerDomNode);\n }\n});\n\nexport { Bounce, Flip, Slide, ToastContainer, POSITION as ToastPosition, TYPE as ToastType, Zoom, cssTransition, toast };\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}","'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","import _classCallCheck from \"@babel/runtime/helpers/classCallCheck\";\nimport _createClass from \"@babel/runtime/helpers/createClass\";\nimport _defineProperty from \"@babel/runtime/helpers/defineProperty\";\n\nfunction ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }\n\nimport React from 'react';\nvar defaultOptions = {\n bindI18n: 'languageChanged',\n bindI18nStore: '',\n // nsMode: 'fallback' // loop through all namespaces given to hook, HOC, render prop for key lookup\n transEmptyNodeValue: '',\n transSupportBasicHtmlNodes: true,\n transKeepBasicHtmlNodesFor: ['br', 'strong', 'i', 'p'],\n // hashTransKey: key => key // calculate a key for Trans component based on defaultValue\n useSuspense: true\n};\nvar i18nInstance;\nvar hasUsedI18nextProvider;\nexport var I18nContext = React.createContext();\nexport function usedI18nextProvider(used) {\n hasUsedI18nextProvider = used;\n}\nexport function getHasUsedI18nextProvider() {\n return hasUsedI18nextProvider;\n}\nexport function setDefaults() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n defaultOptions = _objectSpread({}, defaultOptions, {}, options);\n}\nexport function getDefaults() {\n return defaultOptions;\n}\nexport var ReportNamespaces =\n/*#__PURE__*/\nfunction () {\n function ReportNamespaces() {\n _classCallCheck(this, ReportNamespaces);\n\n this.usedNamespaces = {};\n }\n\n _createClass(ReportNamespaces, [{\n key: \"addUsedNamespaces\",\n value: function addUsedNamespaces(namespaces) {\n var _this = this;\n\n namespaces.forEach(function (ns) {\n if (!_this.usedNamespaces[ns]) _this.usedNamespaces[ns] = true;\n });\n }\n }, {\n key: \"getUsedNamespaces\",\n value: function getUsedNamespaces() {\n return Object.keys(this.usedNamespaces);\n }\n }]);\n\n return ReportNamespaces;\n}();\nexport function setI18n(instance) {\n i18nInstance = instance;\n}\nexport function getI18n() {\n return i18nInstance;\n}\nexport var initReactI18next = {\n type: '3rdParty',\n init: function init(instance) {\n setDefaults(instance.options.react);\n setI18n(instance);\n }\n};\nexport function composeInitialProps(ForComponent) {\n return function (ctx) {\n return new Promise(function (resolve) {\n var i18nInitialProps = getInitialProps();\n\n if (ForComponent.getInitialProps) {\n ForComponent.getInitialProps(ctx).then(function (componentsInitialProps) {\n resolve(_objectSpread({}, componentsInitialProps, {}, i18nInitialProps));\n });\n } else {\n resolve(i18nInitialProps);\n }\n });\n }; // Avoid async for now - so we do not need to pull in regenerator\n // return async ctx => {\n // const componentsInitialProps = ForComponent.getInitialProps\n // ? await ForComponent.getInitialProps(ctx)\n // : {};\n // const i18nInitialProps = getInitialProps();\n // return {\n // ...componentsInitialProps,\n // ...i18nInitialProps,\n // };\n // };\n}\nexport function getInitialProps() {\n var i18n = getI18n();\n var namespaces = i18n.reportNamespaces ? i18n.reportNamespaces.getUsedNamespaces() : [];\n var ret = {};\n var initialI18nStore = {};\n i18n.languages.forEach(function (l) {\n initialI18nStore[l] = {};\n namespaces.forEach(function (ns) {\n initialI18nStore[l][ns] = i18n.getResourceBundle(l, ns) || {};\n });\n });\n ret.initialI18nStore = initialI18nStore;\n ret.initialLanguage = i18n.language;\n return ret;\n}","export function warn() {\n if (console && console.warn) {\n var _console;\n\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n if (typeof args[0] === 'string') args[0] = \"react-i18next:: \".concat(args[0]);\n\n (_console = console).warn.apply(_console, args);\n }\n}\nvar alreadyWarned = {};\nexport function warnOnce() {\n for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\n args[_key2] = arguments[_key2];\n }\n\n if (typeof args[0] === 'string' && alreadyWarned[args[0]]) return;\n if (typeof args[0] === 'string') alreadyWarned[args[0]] = new Date();\n warn.apply(void 0, args);\n} // not needed right now\n//\n// export function deprecated(...args) {\n// if (process && process.env && (!process.env.NODE_ENV || process.env.NODE_ENV === 'development')) {\n// if (typeof args[0] === 'string') args[0] = `deprecation warning -> ${args[0]}`;\n// warnOnce(...args);\n// }\n// }\n\nexport function loadNamespaces(i18n, ns, cb) {\n i18n.loadNamespaces(ns, function () {\n // delay ready if not yet initialized i18n instance\n if (i18n.isInitialized) {\n cb();\n } else {\n var initialized = function initialized() {\n // due to emitter removing issue in i18next we need to delay remove\n setTimeout(function () {\n i18n.off('initialized', initialized);\n }, 0);\n cb();\n };\n\n i18n.on('initialized', initialized);\n }\n });\n}\nexport function hasLoadedNamespace(ns, i18n) {\n var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n\n if (!i18n.languages || !i18n.languages.length) {\n warnOnce('i18n.languages were undefined or empty', i18n.languages);\n return true;\n }\n\n var lng = i18n.languages[0];\n var fallbackLng = i18n.options ? i18n.options.fallbackLng : false;\n var lastLng = i18n.languages[i18n.languages.length - 1]; // we're in cimode so this shall pass\n\n if (lng.toLowerCase() === 'cimode') return true;\n\n var loadNotPending = function loadNotPending(l, n) {\n var loadState = i18n.services.backendConnector.state[\"\".concat(l, \"|\").concat(n)];\n return loadState === -1 || loadState === 2;\n }; // bound to trigger on event languageChanging\n // so set ready to false while we are changing the language\n // and namespace pending (depends on having a backend)\n\n\n if (options.bindI18n && options.bindI18n.indexOf('languageChanging') > -1 && i18n.services.backendConnector.backend && i18n.isLanguageChangingTo && !loadNotPending(i18n.isLanguageChangingTo, ns)) return false; // loaded -> SUCCESS\n\n if (i18n.hasResourceBundle(lng, ns)) return true; // were not loading at all -> SEMI SUCCESS\n\n if (!i18n.services.backendConnector.backend) return true; // failed loading ns - but at least fallback is not pending -> SEMI SUCCESS\n\n if (loadNotPending(lng, ns) && (!fallbackLng || loadNotPending(lastLng, ns))) return true;\n return false;\n}\nexport function getDisplayName(Component) {\n return Component.displayName || Component.name || (typeof Component === 'string' && Component.length > 0 ? Component : 'Unknown');\n}","import _slicedToArray from \"@babel/runtime/helpers/slicedToArray\";\nimport _defineProperty from \"@babel/runtime/helpers/defineProperty\";\n\nfunction ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }\n\nimport { useState, useEffect, useContext } from 'react';\nimport { getI18n, getDefaults, ReportNamespaces, getHasUsedI18nextProvider, I18nContext } from './context';\nimport { warnOnce, loadNamespaces, hasLoadedNamespace } from './utils';\nexport function useTranslation(ns) {\n var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n // assert we have the needed i18nInstance\n var i18nFromProps = props.i18n;\n var ReactI18nContext = useContext(I18nContext);\n\n var _ref = getHasUsedI18nextProvider() ? ReactI18nContext || {} : {},\n i18nFromContext = _ref.i18n,\n defaultNSFromContext = _ref.defaultNS;\n\n var i18n = i18nFromProps || i18nFromContext || getI18n();\n if (i18n && !i18n.reportNamespaces) i18n.reportNamespaces = new ReportNamespaces();\n\n if (!i18n) {\n warnOnce('You will need pass in an i18next instance by using initReactI18next');\n\n var notReadyT = function notReadyT(k) {\n return Array.isArray(k) ? k[k.length - 1] : k;\n };\n\n var retNotReady = [notReadyT, {}, false];\n retNotReady.t = notReadyT;\n retNotReady.i18n = {};\n retNotReady.ready = false;\n return retNotReady;\n }\n\n var i18nOptions = _objectSpread({}, getDefaults(), {}, i18n.options.react, {}, props);\n\n var useSuspense = i18nOptions.useSuspense; // prepare having a namespace\n\n var namespaces = ns || defaultNSFromContext || i18n.options && i18n.options.defaultNS;\n namespaces = typeof namespaces === 'string' ? [namespaces] : namespaces || ['translation']; // report namespaces as used\n\n if (i18n.reportNamespaces.addUsedNamespaces) i18n.reportNamespaces.addUsedNamespaces(namespaces); // are we ready? yes if all namespaces in first language are loaded already (either with data or empty object on failed load)\n\n var ready = (i18n.isInitialized || i18n.initializedStoreOnce) && namespaces.every(function (n) {\n return hasLoadedNamespace(n, i18n, i18nOptions);\n }); // binding t function to namespace (acts also as rerender trigger)\n\n function getT() {\n return {\n t: i18n.getFixedT(null, i18nOptions.nsMode === 'fallback' ? namespaces : namespaces[0])\n };\n }\n\n var _useState = useState(getT()),\n _useState2 = _slicedToArray(_useState, 2),\n t = _useState2[0],\n setT = _useState2[1]; // seems we can't have functions as value -> wrap it in obj\n\n\n useEffect(function () {\n var isMounted = true;\n var bindI18n = i18nOptions.bindI18n,\n bindI18nStore = i18nOptions.bindI18nStore; // if not ready and not using suspense load the namespaces\n // in side effect and do not call resetT if unmounted\n\n if (!ready && !useSuspense) {\n loadNamespaces(i18n, namespaces, function () {\n if (isMounted) setT(getT());\n });\n }\n\n function boundReset() {\n if (isMounted) setT(getT());\n } // bind events to trigger change, like languageChanged\n\n\n if (bindI18n && i18n) i18n.on(bindI18n, boundReset);\n if (bindI18nStore && i18n) i18n.store.on(bindI18nStore, boundReset); // unbinding on unmount\n\n return function () {\n isMounted = false;\n if (bindI18n && i18n) bindI18n.split(' ').forEach(function (e) {\n return i18n.off(e, boundReset);\n });\n if (bindI18nStore && i18n) bindI18nStore.split(' ').forEach(function (e) {\n return i18n.store.off(e, boundReset);\n });\n };\n }, [namespaces.join()]); // re-run effect whenever list of namespaces changes\n\n var ret = [t.t, i18n, ready];\n ret.t = t.t;\n ret.i18n = i18n;\n ret.ready = ready; // return hook stuff if ready\n\n if (ready) return ret; // not yet loaded namespaces -> load them -> and return if useSuspense option set false\n\n if (!ready && !useSuspense) return ret; // not yet loaded namespaces -> load them -> and trigger suspense\n\n throw new Promise(function (resolve) {\n loadNamespaces(i18n, namespaces, function () {\n setT(getT());\n resolve();\n });\n });\n}","import _defineProperty from \"@babel/runtime/helpers/defineProperty\";\nimport _slicedToArray from \"@babel/runtime/helpers/slicedToArray\";\nimport _objectWithoutProperties from \"@babel/runtime/helpers/objectWithoutProperties\";\n\nfunction ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }\n\nimport React from 'react';\nimport { useTranslation } from './useTranslation';\nimport { getDisplayName } from './utils';\nexport function withTranslation(ns) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n return function Extend(WrappedComponent) {\n function I18nextWithTranslation(_ref) {\n var forwardedRef = _ref.forwardedRef,\n rest = _objectWithoutProperties(_ref, [\"forwardedRef\"]);\n\n var _useTranslation = useTranslation(ns, rest),\n _useTranslation2 = _slicedToArray(_useTranslation, 3),\n t = _useTranslation2[0],\n i18n = _useTranslation2[1],\n ready = _useTranslation2[2];\n\n var passDownProps = _objectSpread({}, rest, {\n t: t,\n i18n: i18n,\n tReady: ready\n });\n\n if (options.withRef && forwardedRef) {\n passDownProps.ref = forwardedRef;\n } else if (!options.withRef && forwardedRef) {\n passDownProps.forwardedRef = forwardedRef;\n }\n\n return React.createElement(WrappedComponent, passDownProps);\n }\n\n I18nextWithTranslation.displayName = \"withI18nextTranslation(\".concat(getDisplayName(WrappedComponent), \")\");\n I18nextWithTranslation.WrappedComponent = WrappedComponent;\n\n var forwardRef = function forwardRef(props, ref) {\n return React.createElement(I18nextWithTranslation, Object.assign({}, props, {\n forwardedRef: ref\n }));\n };\n\n return options.withRef ? React.forwardRef(forwardRef) : I18nextWithTranslation;\n };\n}","export { Trans } from './Trans';\nexport { useTranslation } from './useTranslation';\nexport { withTranslation } from './withTranslation';\nexport { Translation } from './Translation';\nexport { I18nextProvider } from './I18nextProvider';\nexport { withSSR } from './withSSR';\nexport { useSSR } from './useSSR';\nexport { I18nContext, initReactI18next, setDefaults, getDefaults, setI18n, getI18n, composeInitialProps, getInitialProps } from './context';","/**\n * @ignore\n * some key-codes definition and utils from closure-library\n * @author yiminghe@gmail.com\n */\nvar KeyCode = {\n /**\n * MAC_ENTER\n */\n MAC_ENTER: 3,\n\n /**\n * BACKSPACE\n */\n BACKSPACE: 8,\n\n /**\n * TAB\n */\n TAB: 9,\n\n /**\n * NUMLOCK on FF/Safari Mac\n */\n NUM_CENTER: 12,\n\n /**\n * ENTER\n */\n ENTER: 13,\n\n /**\n * SHIFT\n */\n SHIFT: 16,\n\n /**\n * CTRL\n */\n CTRL: 17,\n\n /**\n * ALT\n */\n ALT: 18,\n\n /**\n * PAUSE\n */\n PAUSE: 19,\n\n /**\n * CAPS_LOCK\n */\n CAPS_LOCK: 20,\n\n /**\n * ESC\n */\n ESC: 27,\n\n /**\n * SPACE\n */\n SPACE: 32,\n\n /**\n * PAGE_UP\n */\n PAGE_UP: 33,\n\n /**\n * PAGE_DOWN\n */\n PAGE_DOWN: 34,\n\n /**\n * END\n */\n END: 35,\n\n /**\n * HOME\n */\n HOME: 36,\n\n /**\n * LEFT\n */\n LEFT: 37,\n\n /**\n * UP\n */\n UP: 38,\n\n /**\n * RIGHT\n */\n RIGHT: 39,\n\n /**\n * DOWN\n */\n DOWN: 40,\n\n /**\n * PRINT_SCREEN\n */\n PRINT_SCREEN: 44,\n\n /**\n * INSERT\n */\n INSERT: 45,\n\n /**\n * DELETE\n */\n DELETE: 46,\n\n /**\n * ZERO\n */\n ZERO: 48,\n\n /**\n * ONE\n */\n ONE: 49,\n\n /**\n * TWO\n */\n TWO: 50,\n\n /**\n * THREE\n */\n THREE: 51,\n\n /**\n * FOUR\n */\n FOUR: 52,\n\n /**\n * FIVE\n */\n FIVE: 53,\n\n /**\n * SIX\n */\n SIX: 54,\n\n /**\n * SEVEN\n */\n SEVEN: 55,\n\n /**\n * EIGHT\n */\n EIGHT: 56,\n\n /**\n * NINE\n */\n NINE: 57,\n\n /**\n * QUESTION_MARK\n */\n QUESTION_MARK: 63,\n\n /**\n * A\n */\n A: 65,\n\n /**\n * B\n */\n B: 66,\n\n /**\n * C\n */\n C: 67,\n\n /**\n * D\n */\n D: 68,\n\n /**\n * E\n */\n E: 69,\n\n /**\n * F\n */\n F: 70,\n\n /**\n * G\n */\n G: 71,\n\n /**\n * H\n */\n H: 72,\n\n /**\n * I\n */\n I: 73,\n\n /**\n * J\n */\n J: 74,\n\n /**\n * K\n */\n K: 75,\n\n /**\n * L\n */\n L: 76,\n\n /**\n * M\n */\n M: 77,\n\n /**\n * N\n */\n N: 78,\n\n /**\n * O\n */\n O: 79,\n\n /**\n * P\n */\n P: 80,\n\n /**\n * Q\n */\n Q: 81,\n\n /**\n * R\n */\n R: 82,\n\n /**\n * S\n */\n S: 83,\n\n /**\n * T\n */\n T: 84,\n\n /**\n * U\n */\n U: 85,\n\n /**\n * V\n */\n V: 86,\n\n /**\n * W\n */\n W: 87,\n\n /**\n * X\n */\n X: 88,\n\n /**\n * Y\n */\n Y: 89,\n\n /**\n * Z\n */\n Z: 90,\n\n /**\n * META\n */\n META: 91,\n\n /**\n * WIN_KEY_RIGHT\n */\n WIN_KEY_RIGHT: 92,\n\n /**\n * CONTEXT_MENU\n */\n CONTEXT_MENU: 93,\n\n /**\n * NUM_ZERO\n */\n NUM_ZERO: 96,\n\n /**\n * NUM_ONE\n */\n NUM_ONE: 97,\n\n /**\n * NUM_TWO\n */\n NUM_TWO: 98,\n\n /**\n * NUM_THREE\n */\n NUM_THREE: 99,\n\n /**\n * NUM_FOUR\n */\n NUM_FOUR: 100,\n\n /**\n * NUM_FIVE\n */\n NUM_FIVE: 101,\n\n /**\n * NUM_SIX\n */\n NUM_SIX: 102,\n\n /**\n * NUM_SEVEN\n */\n NUM_SEVEN: 103,\n\n /**\n * NUM_EIGHT\n */\n NUM_EIGHT: 104,\n\n /**\n * NUM_NINE\n */\n NUM_NINE: 105,\n\n /**\n * NUM_MULTIPLY\n */\n NUM_MULTIPLY: 106,\n\n /**\n * NUM_PLUS\n */\n NUM_PLUS: 107,\n\n /**\n * NUM_MINUS\n */\n NUM_MINUS: 109,\n\n /**\n * NUM_PERIOD\n */\n NUM_PERIOD: 110,\n\n /**\n * NUM_DIVISION\n */\n NUM_DIVISION: 111,\n\n /**\n * F1\n */\n F1: 112,\n\n /**\n * F2\n */\n F2: 113,\n\n /**\n * F3\n */\n F3: 114,\n\n /**\n * F4\n */\n F4: 115,\n\n /**\n * F5\n */\n F5: 116,\n\n /**\n * F6\n */\n F6: 117,\n\n /**\n * F7\n */\n F7: 118,\n\n /**\n * F8\n */\n F8: 119,\n\n /**\n * F9\n */\n F9: 120,\n\n /**\n * F10\n */\n F10: 121,\n\n /**\n * F11\n */\n F11: 122,\n\n /**\n * F12\n */\n F12: 123,\n\n /**\n * NUMLOCK\n */\n NUMLOCK: 144,\n\n /**\n * SEMICOLON\n */\n SEMICOLON: 186,\n\n /**\n * DASH\n */\n DASH: 189,\n\n /**\n * EQUALS\n */\n EQUALS: 187,\n\n /**\n * COMMA\n */\n COMMA: 188,\n\n /**\n * PERIOD\n */\n PERIOD: 190,\n\n /**\n * SLASH\n */\n SLASH: 191,\n\n /**\n * APOSTROPHE\n */\n APOSTROPHE: 192,\n\n /**\n * SINGLE_QUOTE\n */\n SINGLE_QUOTE: 222,\n\n /**\n * OPEN_SQUARE_BRACKET\n */\n OPEN_SQUARE_BRACKET: 219,\n\n /**\n * BACKSLASH\n */\n BACKSLASH: 220,\n\n /**\n * CLOSE_SQUARE_BRACKET\n */\n CLOSE_SQUARE_BRACKET: 221,\n\n /**\n * WIN_KEY\n */\n WIN_KEY: 224,\n\n /**\n * MAC_FF_META\n */\n MAC_FF_META: 224,\n\n /**\n * WIN_IME\n */\n WIN_IME: 229,\n // ======================== Function ========================\n\n /**\n * whether text and modified key is entered at the same time.\n */\n isTextModifyingKeyEvent: function isTextModifyingKeyEvent(e) {\n var keyCode = e.keyCode;\n\n if (e.altKey && !e.ctrlKey || e.metaKey || // Function keys don't generate text\n keyCode >= KeyCode.F1 && keyCode <= KeyCode.F12) {\n return false;\n } // The following keys are quite harmless, even in combination with\n // CTRL, ALT or SHIFT.\n\n\n switch (keyCode) {\n case KeyCode.ALT:\n case KeyCode.CAPS_LOCK:\n case KeyCode.CONTEXT_MENU:\n case KeyCode.CTRL:\n case KeyCode.DOWN:\n case KeyCode.END:\n case KeyCode.ESC:\n case KeyCode.HOME:\n case KeyCode.INSERT:\n case KeyCode.LEFT:\n case KeyCode.MAC_FF_META:\n case KeyCode.META:\n case KeyCode.NUMLOCK:\n case KeyCode.NUM_CENTER:\n case KeyCode.PAGE_DOWN:\n case KeyCode.PAGE_UP:\n case KeyCode.PAUSE:\n case KeyCode.PRINT_SCREEN:\n case KeyCode.RIGHT:\n case KeyCode.SHIFT:\n case KeyCode.UP:\n case KeyCode.WIN_KEY:\n case KeyCode.WIN_KEY_RIGHT:\n return false;\n\n default:\n return true;\n }\n },\n\n /**\n * whether character is entered.\n */\n isCharacterKey: function isCharacterKey(keyCode) {\n if (keyCode >= KeyCode.ZERO && keyCode <= KeyCode.NINE) {\n return true;\n }\n\n if (keyCode >= KeyCode.NUM_ZERO && keyCode <= KeyCode.NUM_MULTIPLY) {\n return true;\n }\n\n if (keyCode >= KeyCode.A && keyCode <= KeyCode.Z) {\n return true;\n } // Safari sends zero key code for non-latin characters.\n\n\n if (window.navigator.userAgent.indexOf('WebKit') !== -1 && keyCode === 0) {\n return true;\n }\n\n switch (keyCode) {\n case KeyCode.SPACE:\n case KeyCode.QUESTION_MARK:\n case KeyCode.NUM_PLUS:\n case KeyCode.NUM_MINUS:\n case KeyCode.NUM_PERIOD:\n case KeyCode.NUM_DIVISION:\n case KeyCode.SEMICOLON:\n case KeyCode.DASH:\n case KeyCode.EQUALS:\n case KeyCode.COMMA:\n case KeyCode.PERIOD:\n case KeyCode.SLASH:\n case KeyCode.APOSTROPHE:\n case KeyCode.SINGLE_QUOTE:\n case KeyCode.OPEN_SQUARE_BRACKET:\n case KeyCode.BACKSLASH:\n case KeyCode.CLOSE_SQUARE_BRACKET:\n return true;\n\n default:\n return false;\n }\n }\n};\nexport default KeyCode;","/**\n * Safe chained function\n *\n * Will only create a new function if needed,\n * otherwise will pass back existing functions or null.\n *\n * @returns {function|null}\n */\nexport default function createChainedFunction() {\n var args = [].slice.call(arguments, 0);\n\n if (args.length === 1) {\n return args[0];\n }\n\n return function chainedFunction() {\n for (var i = 0; i < args.length; i++) {\n if (args[i] && args[i].apply) {\n args[i].apply(this, arguments);\n }\n }\n };\n}","function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }\n\nfunction _nonIterableRest() { throw new TypeError(\"Invalid attempt to destructure non-iterable instance\"); }\n\nfunction _iterableToArrayLimit(arr, i) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === \"[object Arguments]\")) { return; } var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"] != null) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; }\n\nfunction _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n\n// MIT License from https://github.com/kaimallea/isMobile\nvar applePhone = /iPhone/i;\nvar appleIpod = /iPod/i;\nvar appleTablet = /iPad/i;\nvar androidPhone = /\\bAndroid(?:.+)Mobile\\b/i; // Match 'Android' AND 'Mobile'\n\nvar androidTablet = /Android/i;\nvar amazonPhone = /\\bAndroid(?:.+)SD4930UR\\b/i;\nvar amazonTablet = /\\bAndroid(?:.+)(?:KF[A-Z]{2,4})\\b/i;\nvar windowsPhone = /Windows Phone/i;\nvar windowsTablet = /\\bWindows(?:.+)ARM\\b/i; // Match 'Windows' AND 'ARM'\n\nvar otherBlackberry = /BlackBerry/i;\nvar otherBlackberry10 = /BB10/i;\nvar otherOpera = /Opera Mini/i;\nvar otherChrome = /\\b(CriOS|Chrome)(?:.+)Mobile/i;\nvar otherFirefox = /Mobile(?:.+)Firefox\\b/i; // Match 'Mobile' AND 'Firefox'\n\nfunction match(regex, userAgent) {\n return regex.test(userAgent);\n}\n\nfunction isMobile(userAgent) {\n var ua = userAgent || (typeof navigator !== 'undefined' ? navigator.userAgent : ''); // Facebook mobile app's integrated browser adds a bunch of strings that\n // match everything. Strip it out if it exists.\n\n var tmp = ua.split('[FBAN');\n\n if (typeof tmp[1] !== 'undefined') {\n var _tmp = tmp;\n\n var _tmp2 = _slicedToArray(_tmp, 1);\n\n ua = _tmp2[0];\n } // Twitter mobile app's integrated browser on iPad adds a \"Twitter for\n // iPhone\" string. Same probably happens on other tablet platforms.\n // This will confuse detection so strip it out if it exists.\n\n\n tmp = ua.split('Twitter');\n\n if (typeof tmp[1] !== 'undefined') {\n var _tmp3 = tmp;\n\n var _tmp4 = _slicedToArray(_tmp3, 1);\n\n ua = _tmp4[0];\n }\n\n var result = {\n apple: {\n phone: match(applePhone, ua) && !match(windowsPhone, ua),\n ipod: match(appleIpod, ua),\n tablet: !match(applePhone, ua) && match(appleTablet, ua) && !match(windowsPhone, ua),\n device: (match(applePhone, ua) || match(appleIpod, ua) || match(appleTablet, ua)) && !match(windowsPhone, ua)\n },\n amazon: {\n phone: match(amazonPhone, ua),\n tablet: !match(amazonPhone, ua) && match(amazonTablet, ua),\n device: match(amazonPhone, ua) || match(amazonTablet, ua)\n },\n android: {\n phone: !match(windowsPhone, ua) && match(amazonPhone, ua) || !match(windowsPhone, ua) && match(androidPhone, ua),\n tablet: !match(windowsPhone, ua) && !match(amazonPhone, ua) && !match(androidPhone, ua) && (match(amazonTablet, ua) || match(androidTablet, ua)),\n device: !match(windowsPhone, ua) && (match(amazonPhone, ua) || match(amazonTablet, ua) || match(androidPhone, ua) || match(androidTablet, ua)) || match(/\\bokhttp\\b/i, ua)\n },\n windows: {\n phone: match(windowsPhone, ua),\n tablet: match(windowsTablet, ua),\n device: match(windowsPhone, ua) || match(windowsTablet, ua)\n },\n other: {\n blackberry: match(otherBlackberry, ua),\n blackberry10: match(otherBlackberry10, ua),\n opera: match(otherOpera, ua),\n firefox: match(otherFirefox, ua),\n chrome: match(otherChrome, ua),\n device: match(otherBlackberry, ua) || match(otherBlackberry10, ua) || match(otherOpera, ua) || match(otherFirefox, ua) || match(otherChrome, ua)\n },\n // Additional\n any: null,\n phone: null,\n tablet: null\n };\n result.any = result.apple.device || result.android.device || result.windows.device || result.other.device; // excludes 'other' devices and ipods, targeting touchscreen phones\n\n result.phone = result.apple.phone || result.android.phone || result.windows.phone;\n result.tablet = result.apple.tablet || result.android.tablet || result.windows.tablet;\n return result;\n}\n\nvar defaultResult = _objectSpread({}, isMobile(), {\n isMobile: isMobile\n});\n\nexport default defaultResult;","function _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nimport * as React from 'react';\nimport isMobile from './utils/isMobile';\nexport function noop() {}\nexport function getKeyFromChildrenIndex(child, menuEventKey, index) {\n var prefix = menuEventKey || '';\n return child.key || \"\".concat(prefix, \"item_\").concat(index);\n}\nexport function getMenuIdFromSubMenuEventKey(eventKey) {\n return \"\".concat(eventKey, \"-menu-\");\n}\nexport function loopMenuItem(children, cb) {\n var index = -1;\n React.Children.forEach(children, function (c) {\n index += 1;\n\n if (c && c.type && c.type.isMenuItemGroup) {\n React.Children.forEach(c.props.children, function (c2) {\n index += 1;\n cb(c2, index);\n });\n } else {\n cb(c, index);\n }\n });\n}\nexport function loopMenuItemRecursively(children, keys, ret) {\n /* istanbul ignore if */\n if (!children || ret.find) {\n return;\n }\n\n React.Children.forEach(children, function (c) {\n if (c) {\n var construct = c.type;\n\n if (!construct || !(construct.isSubMenu || construct.isMenuItem || construct.isMenuItemGroup)) {\n return;\n }\n\n if (keys.indexOf(c.key) !== -1) {\n ret.find = true;\n } else if (c.props.children) {\n loopMenuItemRecursively(c.props.children, keys, ret);\n }\n }\n });\n}\nexport var menuAllProps = ['defaultSelectedKeys', 'selectedKeys', 'defaultOpenKeys', 'openKeys', 'mode', 'getPopupContainer', 'onSelect', 'onDeselect', 'onDestroy', 'openTransitionName', 'openAnimation', 'subMenuOpenDelay', 'subMenuCloseDelay', 'forceSubMenuRender', 'triggerSubMenuAction', 'level', 'selectable', 'multiple', 'onOpenChange', 'visible', 'focusable', 'defaultActiveFirst', 'prefixCls', 'inlineIndent', 'parentMenu', 'title', 'rootPrefixCls', 'eventKey', 'active', 'onItemHover', 'onTitleMouseEnter', 'onTitleMouseLeave', 'onTitleClick', 'popupAlign', 'popupOffset', 'isOpen', 'renderMenuItem', 'manualRef', 'subMenuKey', 'disabled', 'index', 'isSelected', 'store', 'activeKey', 'builtinPlacements', 'overflowedIndicator', 'motion', // the following keys found need to be removed from test regression\n'attribute', 'value', 'popupClassName', 'inlineCollapsed', 'menu', 'theme', 'itemIcon', 'expandIcon']; // ref: https://github.com/ant-design/ant-design/issues/14007\n// ref: https://bugs.chromium.org/p/chromium/issues/detail?id=360889\n// getBoundingClientRect return the full precision value, which is\n// not the same behavior as on chrome. Set the precision to 6 to\n// unify their behavior\n\nexport var getWidth = function getWidth(elem) {\n var width = elem && typeof elem.getBoundingClientRect === 'function' && elem.getBoundingClientRect().width;\n\n if (width) {\n width = +width.toFixed(6);\n }\n\n return width || 0;\n};\nexport var setStyle = function setStyle(elem, styleProperty, value) {\n if (elem && _typeof(elem.style) === 'object') {\n elem.style[styleProperty] = value;\n }\n};\nexport var isMobileDevice = function isMobileDevice() {\n return isMobile.any;\n};","export default function contains(root, n) {\n var node = n;\n\n while (node) {\n if (node === root) {\n return true;\n }\n\n node = node.parentNode;\n }\n\n return false;\n}","import addDOMEventListener from 'add-dom-event-listener';\nimport ReactDOM from 'react-dom';\nexport default function addEventListenerWrap(target, eventType, cb, option) {\n /* eslint camelcase: 2 */\n var callback = ReactDOM.unstable_batchedUpdates ? function run(e) {\n ReactDOM.unstable_batchedUpdates(cb, e);\n } : cb;\n return addDOMEventListener(target, eventType, callback, option);\n}","function _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nimport React from 'react';\nimport ReactDOM from 'react-dom';\nimport PropTypes from 'prop-types';\n\nvar ContainerRender =\n/*#__PURE__*/\nfunction (_React$Component) {\n _inherits(ContainerRender, _React$Component);\n\n function ContainerRender() {\n var _getPrototypeOf2;\n\n var _this;\n\n _classCallCheck(this, ContainerRender);\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(ContainerRender)).call.apply(_getPrototypeOf2, [this].concat(args)));\n\n _this.removeContainer = function () {\n if (_this.container) {\n ReactDOM.unmountComponentAtNode(_this.container);\n\n _this.container.parentNode.removeChild(_this.container);\n\n _this.container = null;\n }\n };\n\n _this.renderComponent = function (props, ready) {\n var _this$props = _this.props,\n visible = _this$props.visible,\n getComponent = _this$props.getComponent,\n forceRender = _this$props.forceRender,\n getContainer = _this$props.getContainer,\n parent = _this$props.parent;\n\n if (visible || parent._component || forceRender) {\n if (!_this.container) {\n _this.container = getContainer();\n }\n\n ReactDOM.unstable_renderSubtreeIntoContainer(parent, getComponent(props), _this.container, function callback() {\n if (ready) {\n ready.call(this);\n }\n });\n }\n };\n\n return _this;\n }\n\n _createClass(ContainerRender, [{\n key: \"componentDidMount\",\n value: function componentDidMount() {\n if (this.props.autoMount) {\n this.renderComponent();\n }\n }\n }, {\n key: \"componentDidUpdate\",\n value: function componentDidUpdate() {\n if (this.props.autoMount) {\n this.renderComponent();\n }\n }\n }, {\n key: \"componentWillUnmount\",\n value: function componentWillUnmount() {\n if (this.props.autoDestroy) {\n this.removeContainer();\n }\n }\n }, {\n key: \"render\",\n value: function render() {\n return this.props.children({\n renderComponent: this.renderComponent,\n removeContainer: this.removeContainer\n });\n }\n }]);\n\n return ContainerRender;\n}(React.Component);\n\nContainerRender.propTypes = {\n autoMount: PropTypes.bool,\n autoDestroy: PropTypes.bool,\n visible: PropTypes.bool,\n forceRender: PropTypes.bool,\n parent: PropTypes.any,\n getComponent: PropTypes.func.isRequired,\n getContainer: PropTypes.func.isRequired,\n children: PropTypes.func.isRequired\n};\nContainerRender.defaultProps = {\n autoMount: true,\n autoDestroy: true,\n forceRender: false\n};\nexport { ContainerRender as default };","function _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nimport React from 'react';\nimport ReactDOM from 'react-dom';\nimport PropTypes from 'prop-types';\n\nvar Portal =\n/*#__PURE__*/\nfunction (_React$Component) {\n _inherits(Portal, _React$Component);\n\n function Portal() {\n _classCallCheck(this, Portal);\n\n return _possibleConstructorReturn(this, _getPrototypeOf(Portal).apply(this, arguments));\n }\n\n _createClass(Portal, [{\n key: \"componentDidMount\",\n value: function componentDidMount() {\n this.createContainer();\n }\n }, {\n key: \"componentDidUpdate\",\n value: function componentDidUpdate(prevProps) {\n var didUpdate = this.props.didUpdate;\n\n if (didUpdate) {\n didUpdate(prevProps);\n }\n }\n }, {\n key: \"componentWillUnmount\",\n value: function componentWillUnmount() {\n this.removeContainer();\n }\n }, {\n key: \"createContainer\",\n value: function createContainer() {\n this._container = this.props.getContainer();\n this.forceUpdate();\n }\n }, {\n key: \"removeContainer\",\n value: function removeContainer() {\n if (this._container) {\n this._container.parentNode.removeChild(this._container);\n }\n }\n }, {\n key: \"render\",\n value: function render() {\n if (this._container) {\n return ReactDOM.createPortal(this.props.children, this._container);\n }\n\n return null;\n }\n }]);\n\n return Portal;\n}(React.Component);\n\nPortal.propTypes = {\n getContainer: PropTypes.func.isRequired,\n children: PropTypes.node.isRequired,\n didUpdate: PropTypes.func\n};\nexport { Portal as default };","import _extends from 'babel-runtime/helpers/extends';\nfunction isPointsEq(a1, a2, isAlignPoint) {\n if (isAlignPoint) {\n return a1[0] === a2[0];\n }\n return a1[0] === a2[0] && a1[1] === a2[1];\n}\n\nexport function getAlignFromPlacement(builtinPlacements, placementStr, align) {\n var baseAlign = builtinPlacements[placementStr] || {};\n return _extends({}, baseAlign, align);\n}\n\nexport function getAlignPopupClassName(builtinPlacements, prefixCls, align, isAlignPoint) {\n var points = align.points;\n for (var placement in builtinPlacements) {\n if (builtinPlacements.hasOwnProperty(placement)) {\n if (isPointsEq(builtinPlacements[placement].points, points, isAlignPoint)) {\n return prefixCls + '-placement-' + placement;\n }\n }\n }\n return '';\n}\n\nexport function saveRef(name, component) {\n this[name] = component;\n}","let vendorPrefix;\n\nconst jsCssMap = {\n Webkit: '-webkit-',\n Moz: '-moz-',\n // IE did it wrong again ...\n ms: '-ms-',\n O: '-o-',\n};\n\nfunction getVendorPrefix() {\n if (vendorPrefix !== undefined) {\n return vendorPrefix;\n }\n vendorPrefix = '';\n const style = document.createElement('p').style;\n const testProp = 'Transform';\n for (const key in jsCssMap) {\n if (key + testProp in style) {\n vendorPrefix = key;\n }\n }\n return vendorPrefix;\n}\n\nfunction getTransitionName() {\n return getVendorPrefix()\n ? `${getVendorPrefix()}TransitionProperty`\n : 'transitionProperty';\n}\n\nexport function getTransformName() {\n return getVendorPrefix() ? `${getVendorPrefix()}Transform` : 'transform';\n}\n\nexport function setTransitionProperty(node, value) {\n const name = getTransitionName();\n if (name) {\n node.style[name] = value;\n if (name !== 'transitionProperty') {\n node.style.transitionProperty = value;\n }\n }\n}\n\nfunction setTransform(node, value) {\n const name = getTransformName();\n if (name) {\n node.style[name] = value;\n if (name !== 'transform') {\n node.style.transform = value;\n }\n }\n}\n\nexport function getTransitionProperty(node) {\n return node.style.transitionProperty || node.style[getTransitionName()];\n}\n\nexport function getTransformXY(node) {\n const style = window.getComputedStyle(node, null);\n const transform =\n style.getPropertyValue('transform') ||\n style.getPropertyValue(getTransformName());\n if (transform && transform !== 'none') {\n const matrix = transform.replace(/[^0-9\\-.,]/g, '').split(',');\n return {\n x: parseFloat(matrix[12] || matrix[4], 0),\n y: parseFloat(matrix[13] || matrix[5], 0),\n };\n }\n return {\n x: 0,\n y: 0,\n };\n}\n\nconst matrix2d = /matrix\\((.*)\\)/;\nconst matrix3d = /matrix3d\\((.*)\\)/;\n\nexport function setTransformXY(node, xy) {\n const style = window.getComputedStyle(node, null);\n const transform =\n style.getPropertyValue('transform') ||\n style.getPropertyValue(getTransformName());\n if (transform && transform !== 'none') {\n let arr;\n let match2d = transform.match(matrix2d);\n if (match2d) {\n match2d = match2d[1];\n arr = match2d.split(',').map(item => {\n return parseFloat(item, 10);\n });\n arr[4] = xy.x;\n arr[5] = xy.y;\n setTransform(node, `matrix(${arr.join(',')})`);\n } else {\n const match3d = transform.match(matrix3d)[1];\n arr = match3d.split(',').map(item => {\n return parseFloat(item, 10);\n });\n arr[12] = xy.x;\n arr[13] = xy.y;\n setTransform(node, `matrix3d(${arr.join(',')})`);\n }\n } else {\n setTransform(\n node,\n `translateX(${xy.x}px) translateY(${xy.y}px) translateZ(0)`,\n );\n }\n}\n","import {\n setTransitionProperty,\n getTransitionProperty,\n getTransformXY,\n setTransformXY,\n getTransformName,\n} from './propertyUtils';\n\nconst RE_NUM = /[\\-+]?(?:\\d*\\.|)\\d+(?:[eE][\\-+]?\\d+|)/.source;\n\nlet getComputedStyleX;\n\n// https://stackoverflow.com/a/3485654/3040605\nfunction forceRelayout(elem) {\n const originalStyle = elem.style.display;\n elem.style.display = 'none';\n elem.offsetHeight; // eslint-disable-line\n elem.style.display = originalStyle;\n}\n\nfunction css(el, name, v) {\n let value = v;\n if (typeof name === 'object') {\n for (const i in name) {\n if (name.hasOwnProperty(i)) {\n css(el, i, name[i]);\n }\n }\n return undefined;\n }\n if (typeof value !== 'undefined') {\n if (typeof value === 'number') {\n value = `${value}px`;\n }\n el.style[name] = value;\n return undefined;\n }\n return getComputedStyleX(el, name);\n}\n\nfunction getClientPosition(elem) {\n let box;\n let x;\n let y;\n const doc = elem.ownerDocument;\n const body = doc.body;\n const docElem = doc && doc.documentElement;\n // 根据 GBS 最新数据,A-Grade Browsers 都已支持 getBoundingClientRect 方法,不用再考虑传统的实现方式\n box = elem.getBoundingClientRect();\n\n // 注:jQuery 还考虑减去 docElem.clientLeft/clientTop\n // 但测试发现,这样反而会导致当 html 和 body 有边距/边框样式时,获取的值不正确\n // 此外,ie6 会忽略 html 的 margin 值,幸运地是没有谁会去设置 html 的 margin\n\n x = box.left;\n y = box.top;\n\n // In IE, most of the time, 2 extra pixels are added to the top and left\n // due to the implicit 2-pixel inset border. In IE6/7 quirks mode and\n // IE6 standards mode, this border can be overridden by setting the\n // document element's border to zero -- thus, we cannot rely on the\n // offset always being 2 pixels.\n\n // In quirks mode, the offset can be determined by querying the body's\n // clientLeft/clientTop, but in standards mode, it is found by querying\n // the document element's clientLeft/clientTop. Since we already called\n // getClientBoundingRect we have already forced a reflow, so it is not\n // too expensive just to query them all.\n\n // ie 下应该减去窗口的边框吧,毕竟默认 absolute 都是相对窗口定位的\n // 窗口边框标准是设 documentElement ,quirks 时设置 body\n // 最好禁止在 body 和 html 上边框 ,但 ie < 9 html 默认有 2px ,减去\n // 但是非 ie 不可能设置窗口边框,body html 也不是窗口 ,ie 可以通过 html,body 设置\n // 标准 ie 下 docElem.clientTop 就是 border-top\n // ie7 html 即窗口边框改变不了。永远为 2\n // 但标准 firefox/chrome/ie9 下 docElem.clientTop 是窗口边框,即使设了 border-top 也为 0\n\n x -= docElem.clientLeft || body.clientLeft || 0;\n y -= docElem.clientTop || body.clientTop || 0;\n\n return {\n left: x,\n top: y,\n };\n}\n\nfunction getScroll(w, top) {\n let ret = w[`page${top ? 'Y' : 'X'}Offset`];\n const method = `scroll${top ? 'Top' : 'Left'}`;\n if (typeof ret !== 'number') {\n const d = w.document;\n // ie6,7,8 standard mode\n ret = d.documentElement[method];\n if (typeof ret !== 'number') {\n // quirks mode\n ret = d.body[method];\n }\n }\n return ret;\n}\n\nfunction getScrollLeft(w) {\n return getScroll(w);\n}\n\nfunction getScrollTop(w) {\n return getScroll(w, true);\n}\n\nfunction getOffset(el) {\n const pos = getClientPosition(el);\n const doc = el.ownerDocument;\n const w = doc.defaultView || doc.parentWindow;\n pos.left += getScrollLeft(w);\n pos.top += getScrollTop(w);\n return pos;\n}\n\n/**\n * A crude way of determining if an object is a window\n * @member util\n */\nfunction isWindow(obj) {\n // must use == for ie8\n /* eslint eqeqeq:0 */\n return obj !== null && obj !== undefined && obj == obj.window;\n}\n\nfunction getDocument(node) {\n if (isWindow(node)) {\n return node.document;\n }\n if (node.nodeType === 9) {\n return node;\n }\n return node.ownerDocument;\n}\n\nfunction _getComputedStyle(elem, name, cs) {\n let computedStyle = cs;\n let val = '';\n const d = getDocument(elem);\n computedStyle = computedStyle || d.defaultView.getComputedStyle(elem, null);\n\n // https://github.com/kissyteam/kissy/issues/61\n if (computedStyle) {\n val = computedStyle.getPropertyValue(name) || computedStyle[name];\n }\n\n return val;\n}\n\nconst _RE_NUM_NO_PX = new RegExp(`^(${RE_NUM})(?!px)[a-z%]+$`, 'i');\nconst RE_POS = /^(top|right|bottom|left)$/;\nconst CURRENT_STYLE = 'currentStyle';\nconst RUNTIME_STYLE = 'runtimeStyle';\nconst LEFT = 'left';\nconst PX = 'px';\n\nfunction _getComputedStyleIE(elem, name) {\n // currentStyle maybe null\n // http://msdn.microsoft.com/en-us/library/ms535231.aspx\n let ret = elem[CURRENT_STYLE] && elem[CURRENT_STYLE][name];\n\n // 当 width/height 设置为百分比时,通过 pixelLeft 方式转换的 width/height 值\n // 一开始就处理了! CUSTOM_STYLE.height,CUSTOM_STYLE.width ,cssHook 解决@2011-08-19\n // 在 ie 下不对,需要直接用 offset 方式\n // borderWidth 等值也有问题,但考虑到 borderWidth 设为百分比的概率很小,这里就不考虑了\n\n // From the awesome hack by Dean Edwards\n // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291\n // If we're not dealing with a regular pixel number\n // but a number that has a weird ending, we need to convert it to pixels\n // exclude left right for relativity\n if (_RE_NUM_NO_PX.test(ret) && !RE_POS.test(name)) {\n // Remember the original values\n const style = elem.style;\n const left = style[LEFT];\n const rsLeft = elem[RUNTIME_STYLE][LEFT];\n\n // prevent flashing of content\n elem[RUNTIME_STYLE][LEFT] = elem[CURRENT_STYLE][LEFT];\n\n // Put in the new values to get a computed value out\n style[LEFT] = name === 'fontSize' ? '1em' : ret || 0;\n ret = style.pixelLeft + PX;\n\n // Revert the changed values\n style[LEFT] = left;\n\n elem[RUNTIME_STYLE][LEFT] = rsLeft;\n }\n return ret === '' ? 'auto' : ret;\n}\n\nif (typeof window !== 'undefined') {\n getComputedStyleX = window.getComputedStyle\n ? _getComputedStyle\n : _getComputedStyleIE;\n}\n\nfunction getOffsetDirection(dir, option) {\n if (dir === 'left') {\n return option.useCssRight ? 'right' : dir;\n }\n return option.useCssBottom ? 'bottom' : dir;\n}\n\nfunction oppositeOffsetDirection(dir) {\n if (dir === 'left') {\n return 'right';\n } else if (dir === 'right') {\n return 'left';\n } else if (dir === 'top') {\n return 'bottom';\n } else if (dir === 'bottom') {\n return 'top';\n }\n}\n\n// 设置 elem 相对 elem.ownerDocument 的坐标\nfunction setLeftTop(elem, offset, option) {\n // set position first, in-case top/left are set even on static elem\n if (css(elem, 'position') === 'static') {\n elem.style.position = 'relative';\n }\n let presetH = -999;\n let presetV = -999;\n const horizontalProperty = getOffsetDirection('left', option);\n const verticalProperty = getOffsetDirection('top', option);\n const oppositeHorizontalProperty = oppositeOffsetDirection(\n horizontalProperty,\n );\n const oppositeVerticalProperty = oppositeOffsetDirection(verticalProperty);\n\n if (horizontalProperty !== 'left') {\n presetH = 999;\n }\n\n if (verticalProperty !== 'top') {\n presetV = 999;\n }\n let originalTransition = '';\n const originalOffset = getOffset(elem);\n if ('left' in offset || 'top' in offset) {\n originalTransition = getTransitionProperty(elem) || '';\n setTransitionProperty(elem, 'none');\n }\n if ('left' in offset) {\n elem.style[oppositeHorizontalProperty] = '';\n elem.style[horizontalProperty] = `${presetH}px`;\n }\n if ('top' in offset) {\n elem.style[oppositeVerticalProperty] = '';\n elem.style[verticalProperty] = `${presetV}px`;\n }\n // force relayout\n forceRelayout(elem);\n const old = getOffset(elem);\n const originalStyle = {};\n for (const key in offset) {\n if (offset.hasOwnProperty(key)) {\n const dir = getOffsetDirection(key, option);\n const preset = key === 'left' ? presetH : presetV;\n const off = originalOffset[key] - old[key];\n if (dir === key) {\n originalStyle[dir] = preset + off;\n } else {\n originalStyle[dir] = preset - off;\n }\n }\n }\n css(elem, originalStyle);\n // force relayout\n forceRelayout(elem);\n if ('left' in offset || 'top' in offset) {\n setTransitionProperty(elem, originalTransition);\n }\n const ret = {};\n for (const key in offset) {\n if (offset.hasOwnProperty(key)) {\n const dir = getOffsetDirection(key, option);\n const off = offset[key] - originalOffset[key];\n if (key === dir) {\n ret[dir] = originalStyle[dir] + off;\n } else {\n ret[dir] = originalStyle[dir] - off;\n }\n }\n }\n css(elem, ret);\n}\n\nfunction setTransform(elem, offset) {\n const originalOffset = getOffset(elem);\n const originalXY = getTransformXY(elem);\n const resultXY = { x: originalXY.x, y: originalXY.y };\n if ('left' in offset) {\n resultXY.x = originalXY.x + offset.left - originalOffset.left;\n }\n if ('top' in offset) {\n resultXY.y = originalXY.y + offset.top - originalOffset.top;\n }\n setTransformXY(elem, resultXY);\n}\n\nfunction setOffset(elem, offset, option) {\n if (option.ignoreShake) {\n const oriOffset = getOffset(elem);\n\n const oLeft = oriOffset.left.toFixed(0);\n const oTop = oriOffset.top.toFixed(0);\n const tLeft = offset.left.toFixed(0);\n const tTop = offset.top.toFixed(0);\n\n if (oLeft === tLeft && oTop === tTop) {\n return;\n }\n }\n\n if (option.useCssRight || option.useCssBottom) {\n setLeftTop(elem, offset, option);\n } else if (\n option.useCssTransform &&\n getTransformName() in document.body.style\n ) {\n setTransform(elem, offset, option);\n } else {\n setLeftTop(elem, offset, option);\n }\n}\n\nfunction each(arr, fn) {\n for (let i = 0; i < arr.length; i++) {\n fn(arr[i]);\n }\n}\n\nfunction isBorderBoxFn(elem) {\n return getComputedStyleX(elem, 'boxSizing') === 'border-box';\n}\n\nconst BOX_MODELS = ['margin', 'border', 'padding'];\nconst CONTENT_INDEX = -1;\nconst PADDING_INDEX = 2;\nconst BORDER_INDEX = 1;\nconst MARGIN_INDEX = 0;\n\nfunction swap(elem, options, callback) {\n const old = {};\n const style = elem.style;\n let name;\n\n // Remember the old values, and insert the new ones\n for (name in options) {\n if (options.hasOwnProperty(name)) {\n old[name] = style[name];\n style[name] = options[name];\n }\n }\n\n callback.call(elem);\n\n // Revert the old values\n for (name in options) {\n if (options.hasOwnProperty(name)) {\n style[name] = old[name];\n }\n }\n}\n\nfunction getPBMWidth(elem, props, which) {\n let value = 0;\n let prop;\n let j;\n let i;\n for (j = 0; j < props.length; j++) {\n prop = props[j];\n if (prop) {\n for (i = 0; i < which.length; i++) {\n let cssProp;\n if (prop === 'border') {\n cssProp = `${prop}${which[i]}Width`;\n } else {\n cssProp = prop + which[i];\n }\n value += parseFloat(getComputedStyleX(elem, cssProp)) || 0;\n }\n }\n }\n return value;\n}\n\nconst domUtils = {\n getParent(element) {\n let parent = element;\n do {\n if (parent.nodeType === 11 && parent.host) {\n parent = parent.host;\n } else {\n parent = parent.parentNode;\n }\n } while (parent && parent.nodeType !== 1 && parent.nodeType !== 9);\n return parent;\n },\n};\n\neach(['Width', 'Height'], name => {\n domUtils[`doc${name}`] = refWin => {\n const d = refWin.document;\n return Math.max(\n // firefox chrome documentElement.scrollHeight< body.scrollHeight\n // ie standard mode : documentElement.scrollHeight> body.scrollHeight\n d.documentElement[`scroll${name}`],\n // quirks : documentElement.scrollHeight 最大等于可视窗口多一点?\n d.body[`scroll${name}`],\n domUtils[`viewport${name}`](d),\n );\n };\n\n domUtils[`viewport${name}`] = win => {\n // pc browser includes scrollbar in window.innerWidth\n const prop = `client${name}`;\n const doc = win.document;\n const body = doc.body;\n const documentElement = doc.documentElement;\n const documentElementProp = documentElement[prop];\n // 标准模式取 documentElement\n // backcompat 取 body\n return (\n (doc.compatMode === 'CSS1Compat' && documentElementProp) ||\n (body && body[prop]) ||\n documentElementProp\n );\n };\n});\n\n/*\n 得到元素的大小信息\n @param elem\n @param name\n @param {String} [extra] 'padding' : (css width) + padding\n 'border' : (css width) + padding + border\n 'margin' : (css width) + padding + border + margin\n */\nfunction getWH(elem, name, ex) {\n let extra = ex;\n if (isWindow(elem)) {\n return name === 'width'\n ? domUtils.viewportWidth(elem)\n : domUtils.viewportHeight(elem);\n } else if (elem.nodeType === 9) {\n return name === 'width'\n ? domUtils.docWidth(elem)\n : domUtils.docHeight(elem);\n }\n const which = name === 'width' ? ['Left', 'Right'] : ['Top', 'Bottom'];\n let borderBoxValue =\n name === 'width'\n ? elem.getBoundingClientRect().width\n : elem.getBoundingClientRect().height;\n const computedStyle = getComputedStyleX(elem);\n const isBorderBox = isBorderBoxFn(elem, computedStyle);\n let cssBoxValue = 0;\n if (\n borderBoxValue === null ||\n borderBoxValue === undefined ||\n borderBoxValue <= 0\n ) {\n borderBoxValue = undefined;\n // Fall back to computed then un computed css if necessary\n cssBoxValue = getComputedStyleX(elem, name);\n if (\n cssBoxValue === null ||\n cssBoxValue === undefined ||\n Number(cssBoxValue) < 0\n ) {\n cssBoxValue = elem.style[name] || 0;\n }\n // Normalize '', auto, and prepare for extra\n cssBoxValue = parseFloat(cssBoxValue) || 0;\n }\n if (extra === undefined) {\n extra = isBorderBox ? BORDER_INDEX : CONTENT_INDEX;\n }\n const borderBoxValueOrIsBorderBox =\n borderBoxValue !== undefined || isBorderBox;\n const val = borderBoxValue || cssBoxValue;\n if (extra === CONTENT_INDEX) {\n if (borderBoxValueOrIsBorderBox) {\n return (\n val - getPBMWidth(elem, ['border', 'padding'], which, computedStyle)\n );\n }\n return cssBoxValue;\n } else if (borderBoxValueOrIsBorderBox) {\n if (extra === BORDER_INDEX) {\n return val;\n }\n return (\n val +\n (extra === PADDING_INDEX\n ? -getPBMWidth(elem, ['border'], which, computedStyle)\n : getPBMWidth(elem, ['margin'], which, computedStyle))\n );\n }\n return (\n cssBoxValue +\n getPBMWidth(elem, BOX_MODELS.slice(extra), which, computedStyle)\n );\n}\n\nconst cssShow = {\n position: 'absolute',\n visibility: 'hidden',\n display: 'block',\n};\n\n// fix #119 : https://github.com/kissyteam/kissy/issues/119\nfunction getWHIgnoreDisplay(...args) {\n let val;\n const elem = args[0];\n // in case elem is window\n // elem.offsetWidth === undefined\n if (elem.offsetWidth !== 0) {\n val = getWH.apply(undefined, args);\n } else {\n swap(elem, cssShow, () => {\n val = getWH.apply(undefined, args);\n });\n }\n return val;\n}\n\neach(['width', 'height'], name => {\n const first = name.charAt(0).toUpperCase() + name.slice(1);\n domUtils[`outer${first}`] = (el, includeMargin) => {\n return (\n el &&\n getWHIgnoreDisplay(el, name, includeMargin ? MARGIN_INDEX : BORDER_INDEX)\n );\n };\n const which = name === 'width' ? ['Left', 'Right'] : ['Top', 'Bottom'];\n\n domUtils[name] = (elem, v) => {\n let val = v;\n if (val !== undefined) {\n if (elem) {\n const computedStyle = getComputedStyleX(elem);\n const isBorderBox = isBorderBoxFn(elem);\n if (isBorderBox) {\n val += getPBMWidth(elem, ['padding', 'border'], which, computedStyle);\n }\n return css(elem, name, val);\n }\n return undefined;\n }\n return elem && getWHIgnoreDisplay(elem, name, CONTENT_INDEX);\n };\n});\n\nfunction mix(to, from) {\n for (const i in from) {\n if (from.hasOwnProperty(i)) {\n to[i] = from[i];\n }\n }\n return to;\n}\n\nconst utils = {\n getWindow(node) {\n if (node && node.document && node.setTimeout) {\n return node;\n }\n const doc = node.ownerDocument || node;\n return doc.defaultView || doc.parentWindow;\n },\n getDocument,\n offset(el, value, option) {\n if (typeof value !== 'undefined') {\n setOffset(el, value, option || {});\n } else {\n return getOffset(el);\n }\n },\n isWindow,\n each,\n css,\n clone(obj) {\n let i;\n const ret = {};\n for (i in obj) {\n if (obj.hasOwnProperty(i)) {\n ret[i] = obj[i];\n }\n }\n const overflow = obj.overflow;\n if (overflow) {\n for (i in obj) {\n if (obj.hasOwnProperty(i)) {\n ret.overflow[i] = obj.overflow[i];\n }\n }\n }\n return ret;\n },\n mix,\n getWindowScrollLeft(w) {\n return getScrollLeft(w);\n },\n getWindowScrollTop(w) {\n return getScrollTop(w);\n },\n merge(...args) {\n const ret = {};\n for (let i = 0; i < args.length; i++) {\n utils.mix(ret, args[i]);\n }\n return ret;\n },\n viewportWidth: 0,\n viewportHeight: 0,\n};\n\nmix(utils, domUtils);\n\nexport default utils;\n","import utils from './utils';\n\n/**\n * 得到会导致元素显示不全的祖先元素\n */\nconst { getParent } = utils;\n\nfunction getOffsetParent(element) {\n if (utils.isWindow(element) || element.nodeType === 9) {\n return null;\n }\n // ie 这个也不是完全可行\n /*\n
\n
\n 元素 6 高 100px 宽 50px \n
\n
\n */\n // element.offsetParent does the right thing in ie7 and below. Return parent with layout!\n // In other browsers it only includes elements with position absolute, relative or\n // fixed, not elements with overflow set to auto or scroll.\n // if (UA.ie && ieMode < 8) {\n // return element.offsetParent;\n // }\n // 统一的 offsetParent 方法\n const doc = utils.getDocument(element);\n const body = doc.body;\n let parent;\n let positionStyle = utils.css(element, 'position');\n const skipStatic = positionStyle === 'fixed' || positionStyle === 'absolute';\n\n if (!skipStatic) {\n return element.nodeName.toLowerCase() === 'html'\n ? null\n : getParent(element);\n }\n\n for (\n parent = getParent(element);\n parent && parent !== body && parent.nodeType !== 9;\n parent = getParent(parent)\n ) {\n positionStyle = utils.css(parent, 'position');\n if (positionStyle !== 'static') {\n return parent;\n }\n }\n return null;\n}\n\nexport default getOffsetParent;\n","import utils from './utils';\n\nconst { getParent } = utils;\n\nexport default function isAncestorFixed(element) {\n if (utils.isWindow(element) || element.nodeType === 9) {\n return false;\n }\n\n const doc = utils.getDocument(element);\n const body = doc.body;\n let parent = null;\n for (\n parent = getParent(element);\n parent && parent !== body;\n parent = getParent(parent)\n ) {\n const positionStyle = utils.css(parent, 'position');\n if (positionStyle === 'fixed') {\n return true;\n }\n }\n return false;\n}\n","import utils from './utils';\nimport getOffsetParent from './getOffsetParent';\nimport isAncestorFixed from './isAncestorFixed';\n\n/**\n * 获得元素的显示部分的区域\n */\nfunction getVisibleRectForElement(element) {\n const visibleRect = {\n left: 0,\n right: Infinity,\n top: 0,\n bottom: Infinity,\n };\n let el = getOffsetParent(element);\n const doc = utils.getDocument(element);\n const win = doc.defaultView || doc.parentWindow;\n const body = doc.body;\n const documentElement = doc.documentElement;\n\n // Determine the size of the visible rect by climbing the dom accounting for\n // all scrollable containers.\n while (el) {\n // clientWidth is zero for inline block elements in ie.\n if (\n (navigator.userAgent.indexOf('MSIE') === -1 || el.clientWidth !== 0) &&\n // body may have overflow set on it, yet we still get the entire\n // viewport. In some browsers, el.offsetParent may be\n // document.documentElement, so check for that too.\n (el !== body &&\n el !== documentElement &&\n utils.css(el, 'overflow') !== 'visible')\n ) {\n const pos = utils.offset(el);\n // add border\n pos.left += el.clientLeft;\n pos.top += el.clientTop;\n visibleRect.top = Math.max(visibleRect.top, pos.top);\n visibleRect.right = Math.min(\n visibleRect.right,\n // consider area without scrollBar\n pos.left + el.clientWidth,\n );\n visibleRect.bottom = Math.min(\n visibleRect.bottom,\n pos.top + el.clientHeight,\n );\n visibleRect.left = Math.max(visibleRect.left, pos.left);\n } else if (el === body || el === documentElement) {\n break;\n }\n el = getOffsetParent(el);\n }\n\n // Set element position to fixed\n // make sure absolute element itself don't affect it's visible area\n // https://github.com/ant-design/ant-design/issues/7601\n let originalPosition = null;\n if (!utils.isWindow(element) && element.nodeType !== 9) {\n originalPosition = element.style.position;\n const position = utils.css(element, 'position');\n if (position === 'absolute') {\n element.style.position = 'fixed';\n }\n }\n\n const scrollX = utils.getWindowScrollLeft(win);\n const scrollY = utils.getWindowScrollTop(win);\n const viewportWidth = utils.viewportWidth(win);\n const viewportHeight = utils.viewportHeight(win);\n let documentWidth = documentElement.scrollWidth;\n let documentHeight = documentElement.scrollHeight;\n\n // scrollXXX on html is sync with body which means overflow: hidden on body gets wrong scrollXXX.\n // We should cut this ourself.\n const bodyStyle = window.getComputedStyle(body);\n if (bodyStyle.overflowX === 'hidden') {\n documentWidth = win.innerWidth;\n }\n if (bodyStyle.overflowY === 'hidden') {\n documentHeight = win.innerHeight;\n }\n\n // Reset element position after calculate the visible area\n if (element.style) {\n element.style.position = originalPosition;\n }\n\n if (isAncestorFixed(element)) {\n // Clip by viewport's size.\n visibleRect.left = Math.max(visibleRect.left, scrollX);\n visibleRect.top = Math.max(visibleRect.top, scrollY);\n visibleRect.right = Math.min(visibleRect.right, scrollX + viewportWidth);\n visibleRect.bottom = Math.min(visibleRect.bottom, scrollY + viewportHeight);\n } else {\n // Clip by document's size.\n const maxVisibleWidth = Math.max(documentWidth, scrollX + viewportWidth);\n visibleRect.right = Math.min(visibleRect.right, maxVisibleWidth);\n\n const maxVisibleHeight = Math.max(documentHeight, scrollY + viewportHeight);\n visibleRect.bottom = Math.min(visibleRect.bottom, maxVisibleHeight);\n }\n\n return visibleRect.top >= 0 &&\n visibleRect.left >= 0 &&\n visibleRect.bottom > visibleRect.top &&\n visibleRect.right > visibleRect.left\n ? visibleRect\n : null;\n}\n\nexport default getVisibleRectForElement;\n","import utils from './utils';\n\nfunction getRegion(node) {\n let offset;\n let w;\n let h;\n if (!utils.isWindow(node) && node.nodeType !== 9) {\n offset = utils.offset(node);\n w = utils.outerWidth(node);\n h = utils.outerHeight(node);\n } else {\n const win = utils.getWindow(node);\n offset = {\n left: utils.getWindowScrollLeft(win),\n top: utils.getWindowScrollTop(win),\n };\n w = utils.viewportWidth(win);\n h = utils.viewportHeight(win);\n }\n offset.width = w;\n offset.height = h;\n return offset;\n}\n\nexport default getRegion;\n","/**\n * 获取 node 上的 align 对齐点 相对于页面的坐标\n */\n\nfunction getAlignOffset(region, align) {\n const V = align.charAt(0);\n const H = align.charAt(1);\n const w = region.width;\n const h = region.height;\n\n let x = region.left;\n let y = region.top;\n\n if (V === 'c') {\n y += h / 2;\n } else if (V === 'b') {\n y += h;\n }\n\n if (H === 'c') {\n x += w / 2;\n } else if (H === 'r') {\n x += w;\n }\n\n return {\n left: x,\n top: y,\n };\n}\n\nexport default getAlignOffset;\n","import getAlignOffset from './getAlignOffset';\n\nfunction getElFuturePos(elRegion, refNodeRegion, points, offset, targetOffset) {\n const p1 = getAlignOffset(refNodeRegion, points[1]);\n const p2 = getAlignOffset(elRegion, points[0]);\n const diff = [p2.left - p1.left, p2.top - p1.top];\n\n return {\n left: Math.round(elRegion.left - diff[0] + offset[0] - targetOffset[0]),\n top: Math.round(elRegion.top - diff[1] + offset[1] - targetOffset[1]),\n };\n}\n\nexport default getElFuturePos;\n","/**\n * align dom node flexibly\n * @author yiminghe@gmail.com\n */\n\nimport utils from '../utils';\nimport getVisibleRectForElement from '../getVisibleRectForElement';\nimport adjustForViewport from '../adjustForViewport';\nimport getRegion from '../getRegion';\nimport getElFuturePos from '../getElFuturePos';\n\n// http://yiminghe.iteye.com/blog/1124720\n\nfunction isFailX(elFuturePos, elRegion, visibleRect) {\n return (\n elFuturePos.left < visibleRect.left ||\n elFuturePos.left + elRegion.width > visibleRect.right\n );\n}\n\nfunction isFailY(elFuturePos, elRegion, visibleRect) {\n return (\n elFuturePos.top < visibleRect.top ||\n elFuturePos.top + elRegion.height > visibleRect.bottom\n );\n}\n\nfunction isCompleteFailX(elFuturePos, elRegion, visibleRect) {\n return (\n elFuturePos.left > visibleRect.right ||\n elFuturePos.left + elRegion.width < visibleRect.left\n );\n}\n\nfunction isCompleteFailY(elFuturePos, elRegion, visibleRect) {\n return (\n elFuturePos.top > visibleRect.bottom ||\n elFuturePos.top + elRegion.height < visibleRect.top\n );\n}\n\nfunction flip(points, reg, map) {\n const ret = [];\n utils.each(points, p => {\n ret.push(\n p.replace(reg, m => {\n return map[m];\n }),\n );\n });\n return ret;\n}\n\nfunction flipOffset(offset, index) {\n offset[index] = -offset[index];\n return offset;\n}\n\nfunction convertOffset(str, offsetLen) {\n let n;\n if (/%$/.test(str)) {\n n = (parseInt(str.substring(0, str.length - 1), 10) / 100) * offsetLen;\n } else {\n n = parseInt(str, 10);\n }\n return n || 0;\n}\n\nfunction normalizeOffset(offset, el) {\n offset[0] = convertOffset(offset[0], el.width);\n offset[1] = convertOffset(offset[1], el.height);\n}\n\n/**\n * @param el\n * @param tgtRegion 参照节点所占的区域: { left, top, width, height }\n * @param align\n */\nfunction doAlign(el, tgtRegion, align, isTgtRegionVisible) {\n let points = align.points;\n let offset = align.offset || [0, 0];\n let targetOffset = align.targetOffset || [0, 0];\n let overflow = align.overflow;\n const source = align.source || el;\n offset = [].concat(offset);\n targetOffset = [].concat(targetOffset);\n overflow = overflow || {};\n const newOverflowCfg = {};\n let fail = 0;\n // 当前节点可以被放置的显示区域\n const visibleRect = getVisibleRectForElement(source);\n // 当前节点所占的区域, left/top/width/height\n const elRegion = getRegion(source);\n // 将 offset 转换成数值,支持百分比\n normalizeOffset(offset, elRegion);\n normalizeOffset(targetOffset, tgtRegion);\n // 当前节点将要被放置的位置\n let elFuturePos = getElFuturePos(\n elRegion,\n tgtRegion,\n points,\n offset,\n targetOffset,\n );\n // 当前节点将要所处的区域\n let newElRegion = utils.merge(elRegion, elFuturePos);\n\n // 如果可视区域不能完全放置当前节点时允许调整\n if (\n visibleRect &&\n (overflow.adjustX || overflow.adjustY) &&\n isTgtRegionVisible\n ) {\n if (overflow.adjustX) {\n // 如果横向不能放下\n if (isFailX(elFuturePos, elRegion, visibleRect)) {\n // 对齐位置反下\n const newPoints = flip(points, /[lr]/gi, {\n l: 'r',\n r: 'l',\n });\n // 偏移量也反下\n const newOffset = flipOffset(offset, 0);\n const newTargetOffset = flipOffset(targetOffset, 0);\n const newElFuturePos = getElFuturePos(\n elRegion,\n tgtRegion,\n newPoints,\n newOffset,\n newTargetOffset,\n );\n\n if (!isCompleteFailX(newElFuturePos, elRegion, visibleRect)) {\n fail = 1;\n points = newPoints;\n offset = newOffset;\n targetOffset = newTargetOffset;\n }\n }\n }\n\n if (overflow.adjustY) {\n // 如果纵向不能放下\n if (isFailY(elFuturePos, elRegion, visibleRect)) {\n // 对齐位置反下\n const newPoints = flip(points, /[tb]/gi, {\n t: 'b',\n b: 't',\n });\n // 偏移量也反下\n const newOffset = flipOffset(offset, 1);\n const newTargetOffset = flipOffset(targetOffset, 1);\n const newElFuturePos = getElFuturePos(\n elRegion,\n tgtRegion,\n newPoints,\n newOffset,\n newTargetOffset,\n );\n\n if (!isCompleteFailY(newElFuturePos, elRegion, visibleRect)) {\n fail = 1;\n points = newPoints;\n offset = newOffset;\n targetOffset = newTargetOffset;\n }\n }\n }\n\n // 如果失败,重新计算当前节点将要被放置的位置\n if (fail) {\n elFuturePos = getElFuturePos(\n elRegion,\n tgtRegion,\n points,\n offset,\n targetOffset,\n );\n utils.mix(newElRegion, elFuturePos);\n }\n const isStillFailX = isFailX(elFuturePos, elRegion, visibleRect);\n const isStillFailY = isFailY(elFuturePos, elRegion, visibleRect);\n // 检查反下后的位置是否可以放下了,如果仍然放不下:\n // 1. 复原修改过的定位参数\n if (isStillFailX || isStillFailY) {\n points = align.points;\n offset = align.offset || [0, 0];\n targetOffset = align.targetOffset || [0, 0];\n }\n // 2. 只有指定了可以调整当前方向才调整\n newOverflowCfg.adjustX = overflow.adjustX && isStillFailX;\n newOverflowCfg.adjustY = overflow.adjustY && isStillFailY;\n\n // 确实要调整,甚至可能会调整高度宽度\n if (newOverflowCfg.adjustX || newOverflowCfg.adjustY) {\n newElRegion = adjustForViewport(\n elFuturePos,\n elRegion,\n visibleRect,\n newOverflowCfg,\n );\n }\n }\n\n // need judge to in case set fixed with in css on height auto element\n if (newElRegion.width !== elRegion.width) {\n utils.css(\n source,\n 'width',\n utils.width(source) + newElRegion.width - elRegion.width,\n );\n }\n\n if (newElRegion.height !== elRegion.height) {\n utils.css(\n source,\n 'height',\n utils.height(source) + newElRegion.height - elRegion.height,\n );\n }\n\n // https://github.com/kissyteam/kissy/issues/190\n // 相对于屏幕位置没变,而 left/top 变了\n // 例如
\n utils.offset(\n source,\n {\n left: newElRegion.left,\n top: newElRegion.top,\n },\n {\n useCssRight: align.useCssRight,\n useCssBottom: align.useCssBottom,\n useCssTransform: align.useCssTransform,\n ignoreShake: align.ignoreShake,\n },\n );\n\n return {\n points,\n offset,\n targetOffset,\n overflow: newOverflowCfg,\n };\n}\n\nexport default doAlign;\n/**\n * 2012-04-26 yiminghe@gmail.com\n * - 优化智能对齐算法\n * - 慎用 resizeXX\n *\n * 2011-07-13 yiminghe@gmail.com note:\n * - 增加智能对齐,以及大小调整选项\n **/\n","import utils from './utils';\n\nfunction adjustForViewport(elFuturePos, elRegion, visibleRect, overflow) {\n const pos = utils.clone(elFuturePos);\n const size = {\n width: elRegion.width,\n height: elRegion.height,\n };\n\n if (overflow.adjustX && pos.left < visibleRect.left) {\n pos.left = visibleRect.left;\n }\n\n // Left edge inside and right edge outside viewport, try to resize it.\n if (\n overflow.resizeWidth &&\n pos.left >= visibleRect.left &&\n pos.left + size.width > visibleRect.right\n ) {\n size.width -= pos.left + size.width - visibleRect.right;\n }\n\n // Right edge outside viewport, try to move it.\n if (overflow.adjustX && pos.left + size.width > visibleRect.right) {\n // 保证左边界和可视区域左边界对齐\n pos.left = Math.max(visibleRect.right - size.width, visibleRect.left);\n }\n\n // Top edge outside viewport, try to move it.\n if (overflow.adjustY && pos.top < visibleRect.top) {\n pos.top = visibleRect.top;\n }\n\n // Top edge inside and bottom edge outside viewport, try to resize it.\n if (\n overflow.resizeHeight &&\n pos.top >= visibleRect.top &&\n pos.top + size.height > visibleRect.bottom\n ) {\n size.height -= pos.top + size.height - visibleRect.bottom;\n }\n\n // Bottom edge outside viewport, try to move it.\n if (overflow.adjustY && pos.top + size.height > visibleRect.bottom) {\n // 保证上边界和可视区域上边界对齐\n pos.top = Math.max(visibleRect.bottom - size.height, visibleRect.top);\n }\n\n return utils.mix(pos, size);\n}\n\nexport default adjustForViewport;\n","import doAlign from './align';\nimport getOffsetParent from '../getOffsetParent';\nimport getVisibleRectForElement from '../getVisibleRectForElement';\nimport getRegion from '../getRegion';\n\nfunction isOutOfVisibleRect(target) {\n const visibleRect = getVisibleRectForElement(target);\n const targetRegion = getRegion(target);\n\n return (\n !visibleRect ||\n targetRegion.left + targetRegion.width <= visibleRect.left ||\n targetRegion.top + targetRegion.height <= visibleRect.top ||\n targetRegion.left >= visibleRect.right ||\n targetRegion.top >= visibleRect.bottom\n );\n}\n\nfunction alignElement(el, refNode, align) {\n const target = align.target || refNode;\n const refNodeRegion = getRegion(target);\n\n const isTargetNotOutOfVisible = !isOutOfVisibleRect(target);\n\n return doAlign(el, refNodeRegion, align, isTargetNotOutOfVisible);\n}\n\nalignElement.__getOffsetParent = getOffsetParent;\n\nalignElement.__getVisibleRectForElement = getVisibleRectForElement;\n\nexport default alignElement;\n","import utils from '../utils';\nimport doAlign from './align';\n\n/**\n * `tgtPoint`: { pageX, pageY } or { clientX, clientY }.\n * If client position provided, will internal convert to page position.\n */\n\nfunction alignPoint(el, tgtPoint, align) {\n let pageX;\n let pageY;\n\n const doc = utils.getDocument(el);\n const win = doc.defaultView || doc.parentWindow;\n\n const scrollX = utils.getWindowScrollLeft(win);\n const scrollY = utils.getWindowScrollTop(win);\n const viewportWidth = utils.viewportWidth(win);\n const viewportHeight = utils.viewportHeight(win);\n\n if ('pageX' in tgtPoint) {\n pageX = tgtPoint.pageX;\n } else {\n pageX = scrollX + tgtPoint.clientX;\n }\n\n if ('pageY' in tgtPoint) {\n pageY = tgtPoint.pageY;\n } else {\n pageY = scrollY + tgtPoint.clientY;\n }\n\n const tgtRegion = {\n left: pageX,\n top: pageY,\n width: 0,\n height: 0,\n };\n\n const pointInView =\n pageX >= 0 &&\n pageX <= scrollX + viewportWidth &&\n (pageY >= 0 && pageY <= scrollY + viewportHeight);\n\n // Provide default target point\n const points = [align.points[0], 'cc'];\n\n return doAlign(el, tgtRegion, { ...align, points }, pointInView);\n}\n\nexport default alignPoint;\n","import contains from 'rc-util/es/Dom/contains';\n\nexport function buffer(fn, ms) {\n var timer = void 0;\n\n function clear() {\n if (timer) {\n clearTimeout(timer);\n timer = null;\n }\n }\n\n function bufferFn() {\n clear();\n timer = setTimeout(fn, ms);\n }\n\n bufferFn.clear = clear;\n\n return bufferFn;\n}\n\nexport function isSamePoint(prev, next) {\n if (prev === next) return true;\n if (!prev || !next) return false;\n\n if ('pageX' in next && 'pageY' in next) {\n return prev.pageX === next.pageX && prev.pageY === next.pageY;\n }\n\n if ('clientX' in next && 'clientY' in next) {\n return prev.clientX === next.clientX && prev.clientY === next.clientY;\n }\n\n return false;\n}\n\nexport function isWindow(obj) {\n return obj && typeof obj === 'object' && obj.window === obj;\n}\n\nexport function isSimilarValue(val1, val2) {\n var int1 = Math.floor(val1);\n var int2 = Math.floor(val2);\n return Math.abs(int1 - int2) <= 1;\n}\n\nexport function restoreFocus(activeElement, container) {\n // Focus back if is in the container\n if (activeElement !== document.activeElement && contains(container, activeElement)) {\n activeElement.focus();\n }\n}","import _classCallCheck from 'babel-runtime/helpers/classCallCheck';\nimport _createClass from 'babel-runtime/helpers/createClass';\nimport _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';\nimport _inherits from 'babel-runtime/helpers/inherits';\nimport React, { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport ReactDOM from 'react-dom';\nimport { alignElement, alignPoint } from 'dom-align';\nimport addEventListener from 'rc-util/es/Dom/addEventListener';\n\nimport { isWindow, buffer, isSamePoint, isSimilarValue, restoreFocus } from './util';\n\nfunction getElement(func) {\n if (typeof func !== 'function' || !func) return null;\n return func();\n}\n\nfunction getPoint(point) {\n if (typeof point !== 'object' || !point) return null;\n return point;\n}\n\nvar Align = function (_Component) {\n _inherits(Align, _Component);\n\n function Align() {\n var _ref;\n\n var _temp, _this, _ret;\n\n _classCallCheck(this, Align);\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, (_ref = Align.__proto__ || Object.getPrototypeOf(Align)).call.apply(_ref, [this].concat(args))), _this), _this.forceAlign = function () {\n var _this$props = _this.props,\n disabled = _this$props.disabled,\n target = _this$props.target,\n align = _this$props.align,\n onAlign = _this$props.onAlign;\n\n if (!disabled && target) {\n var source = ReactDOM.findDOMNode(_this);\n\n var result = void 0;\n var element = getElement(target);\n var point = getPoint(target);\n\n // IE lose focus after element realign\n // We should record activeElement and restore later\n var activeElement = document.activeElement;\n\n if (element) {\n result = alignElement(source, element, align);\n } else if (point) {\n result = alignPoint(source, point, align);\n }\n\n restoreFocus(activeElement, source);\n\n if (onAlign) {\n onAlign(source, result);\n }\n }\n }, _temp), _possibleConstructorReturn(_this, _ret);\n }\n\n _createClass(Align, [{\n key: 'componentDidMount',\n value: function componentDidMount() {\n var props = this.props;\n // if parent ref not attached .... use document.getElementById\n this.forceAlign();\n if (!props.disabled && props.monitorWindowResize) {\n this.startMonitorWindowResize();\n }\n }\n }, {\n key: 'componentDidUpdate',\n value: function componentDidUpdate(prevProps) {\n var reAlign = false;\n var props = this.props;\n\n if (!props.disabled) {\n var source = ReactDOM.findDOMNode(this);\n var sourceRect = source ? source.getBoundingClientRect() : null;\n\n if (prevProps.disabled) {\n reAlign = true;\n } else {\n var lastElement = getElement(prevProps.target);\n var currentElement = getElement(props.target);\n var lastPoint = getPoint(prevProps.target);\n var currentPoint = getPoint(props.target);\n\n if (isWindow(lastElement) && isWindow(currentElement)) {\n // Skip if is window\n reAlign = false;\n } else if (lastElement !== currentElement || // Element change\n lastElement && !currentElement && currentPoint || // Change from element to point\n lastPoint && currentPoint && currentElement || // Change from point to element\n currentPoint && !isSamePoint(lastPoint, currentPoint)) {\n reAlign = true;\n }\n\n // If source element size changed\n var preRect = this.sourceRect || {};\n if (!reAlign && source && (!isSimilarValue(preRect.width, sourceRect.width) || !isSimilarValue(preRect.height, sourceRect.height))) {\n reAlign = true;\n }\n }\n\n this.sourceRect = sourceRect;\n }\n\n if (reAlign) {\n this.forceAlign();\n }\n\n if (props.monitorWindowResize && !props.disabled) {\n this.startMonitorWindowResize();\n } else {\n this.stopMonitorWindowResize();\n }\n }\n }, {\n key: 'componentWillUnmount',\n value: function componentWillUnmount() {\n this.stopMonitorWindowResize();\n }\n }, {\n key: 'startMonitorWindowResize',\n value: function startMonitorWindowResize() {\n if (!this.resizeHandler) {\n this.bufferMonitor = buffer(this.forceAlign, this.props.monitorBufferTime);\n this.resizeHandler = addEventListener(window, 'resize', this.bufferMonitor);\n }\n }\n }, {\n key: 'stopMonitorWindowResize',\n value: function stopMonitorWindowResize() {\n if (this.resizeHandler) {\n this.bufferMonitor.clear();\n this.resizeHandler.remove();\n this.resizeHandler = null;\n }\n }\n }, {\n key: 'render',\n value: function render() {\n var _this2 = this;\n\n var _props = this.props,\n childrenProps = _props.childrenProps,\n children = _props.children;\n\n var child = React.Children.only(children);\n if (childrenProps) {\n var newProps = {};\n var propList = Object.keys(childrenProps);\n propList.forEach(function (prop) {\n newProps[prop] = _this2.props[childrenProps[prop]];\n });\n\n return React.cloneElement(child, newProps);\n }\n return child;\n }\n }]);\n\n return Align;\n}(Component);\n\nAlign.propTypes = {\n childrenProps: PropTypes.object,\n align: PropTypes.object.isRequired,\n target: PropTypes.oneOfType([PropTypes.func, PropTypes.shape({\n clientX: PropTypes.number,\n clientY: PropTypes.number,\n pageX: PropTypes.number,\n pageY: PropTypes.number\n })]),\n onAlign: PropTypes.func,\n monitorBufferTime: PropTypes.number,\n monitorWindowResize: PropTypes.bool,\n disabled: PropTypes.bool,\n children: PropTypes.any\n};\nAlign.defaultProps = {\n target: function target() {\n return window;\n },\n monitorBufferTime: 50,\n monitorWindowResize: false,\n disabled: false\n};\n\n\nexport default Align;","// export this package's api\nimport Align from './Align';\n\nexport default Align;","import React from 'react';\n\nvar unsafeLifecyclesPolyfill = function unsafeLifecyclesPolyfill(Component) {\n var prototype = Component.prototype;\n\n if (!prototype || !prototype.isReactComponent) {\n throw new Error('Can only polyfill class components');\n } // only handle componentWillReceiveProps\n\n\n if (typeof prototype.componentWillReceiveProps !== 'function') {\n return Component;\n } // In React 16.9, React.Profiler was introduced together with UNSAFE_componentWillReceiveProps\n // https://reactjs.org/blog/2019/08/08/react-v16.9.0.html#performance-measurements-with-reactprofiler\n\n\n if (!React.Profiler) {\n return Component;\n } // Here polyfill get started\n\n\n prototype.UNSAFE_componentWillReceiveProps = prototype.componentWillReceiveProps;\n delete prototype.componentWillReceiveProps;\n return Component;\n};\n\nexport default unsafeLifecyclesPolyfill;","import React from 'react';\n\nexport function toArrayChildren(children) {\n var ret = [];\n React.Children.forEach(children, function (child) {\n ret.push(child);\n });\n return ret;\n}\n\nexport function findChildInChildrenByKey(children, key) {\n var ret = null;\n if (children) {\n children.forEach(function (child) {\n if (ret) {\n return;\n }\n if (child && child.key === key) {\n ret = child;\n }\n });\n }\n return ret;\n}\n\nexport function findShownChildInChildrenByKey(children, key, showProp) {\n var ret = null;\n if (children) {\n children.forEach(function (child) {\n if (child && child.key === key && child.props[showProp]) {\n if (ret) {\n throw new Error('two child with same key for children');\n }\n ret = child;\n }\n });\n }\n return ret;\n}\n\nexport function findHiddenChildInChildrenByKey(children, key, showProp) {\n var found = 0;\n if (children) {\n children.forEach(function (child) {\n if (found) {\n return;\n }\n found = child && child.key === key && !child.props[showProp];\n });\n }\n return found;\n}\n\nexport function isSameChildren(c1, c2, showProp) {\n var same = c1.length === c2.length;\n if (same) {\n c1.forEach(function (child, index) {\n var child2 = c2[index];\n if (child && child2) {\n if (child && !child2 || !child && child2) {\n same = false;\n } else if (child.key !== child2.key) {\n same = false;\n } else if (showProp && child.props[showProp] !== child2.props[showProp]) {\n same = false;\n }\n }\n });\n }\n return same;\n}\n\nexport function mergeChildren(prev, next) {\n var ret = [];\n\n // For each key of `next`, the list of keys to insert before that key in\n // the combined list\n var nextChildrenPending = {};\n var pendingChildren = [];\n prev.forEach(function (child) {\n if (child && findChildInChildrenByKey(next, child.key)) {\n if (pendingChildren.length) {\n nextChildrenPending[child.key] = pendingChildren;\n pendingChildren = [];\n }\n } else {\n pendingChildren.push(child);\n }\n });\n\n next.forEach(function (child) {\n if (child && Object.prototype.hasOwnProperty.call(nextChildrenPending, child.key)) {\n ret = ret.concat(nextChildrenPending[child.key]);\n }\n ret.push(child);\n });\n\n ret = ret.concat(pendingChildren);\n\n return ret;\n}","var START_EVENT_NAME_MAP = {\n transitionstart: {\n transition: 'transitionstart',\n WebkitTransition: 'webkitTransitionStart',\n MozTransition: 'mozTransitionStart',\n OTransition: 'oTransitionStart',\n msTransition: 'MSTransitionStart'\n },\n\n animationstart: {\n animation: 'animationstart',\n WebkitAnimation: 'webkitAnimationStart',\n MozAnimation: 'mozAnimationStart',\n OAnimation: 'oAnimationStart',\n msAnimation: 'MSAnimationStart'\n }\n};\n\nvar END_EVENT_NAME_MAP = {\n transitionend: {\n transition: 'transitionend',\n WebkitTransition: 'webkitTransitionEnd',\n MozTransition: 'mozTransitionEnd',\n OTransition: 'oTransitionEnd',\n msTransition: 'MSTransitionEnd'\n },\n\n animationend: {\n animation: 'animationend',\n WebkitAnimation: 'webkitAnimationEnd',\n MozAnimation: 'mozAnimationEnd',\n OAnimation: 'oAnimationEnd',\n msAnimation: 'MSAnimationEnd'\n }\n};\n\nvar startEvents = [];\nvar endEvents = [];\n\nfunction detectEvents() {\n var testEl = document.createElement('div');\n var style = testEl.style;\n\n if (!('AnimationEvent' in window)) {\n delete START_EVENT_NAME_MAP.animationstart.animation;\n delete END_EVENT_NAME_MAP.animationend.animation;\n }\n\n if (!('TransitionEvent' in window)) {\n delete START_EVENT_NAME_MAP.transitionstart.transition;\n delete END_EVENT_NAME_MAP.transitionend.transition;\n }\n\n function process(EVENT_NAME_MAP, events) {\n for (var baseEventName in EVENT_NAME_MAP) {\n if (EVENT_NAME_MAP.hasOwnProperty(baseEventName)) {\n var baseEvents = EVENT_NAME_MAP[baseEventName];\n for (var styleName in baseEvents) {\n if (styleName in style) {\n events.push(baseEvents[styleName]);\n break;\n }\n }\n }\n }\n }\n\n process(START_EVENT_NAME_MAP, startEvents);\n process(END_EVENT_NAME_MAP, endEvents);\n}\n\nif (typeof window !== 'undefined' && typeof document !== 'undefined') {\n detectEvents();\n}\n\nfunction addEventListener(node, eventName, eventListener) {\n node.addEventListener(eventName, eventListener, false);\n}\n\nfunction removeEventListener(node, eventName, eventListener) {\n node.removeEventListener(eventName, eventListener, false);\n}\n\nvar TransitionEvents = {\n // Start events\n startEvents: startEvents,\n\n addStartEventListener: function addStartEventListener(node, eventListener) {\n if (startEvents.length === 0) {\n window.setTimeout(eventListener, 0);\n return;\n }\n startEvents.forEach(function (startEvent) {\n addEventListener(node, startEvent, eventListener);\n });\n },\n removeStartEventListener: function removeStartEventListener(node, eventListener) {\n if (startEvents.length === 0) {\n return;\n }\n startEvents.forEach(function (startEvent) {\n removeEventListener(node, startEvent, eventListener);\n });\n },\n\n\n // End events\n endEvents: endEvents,\n\n addEndEventListener: function addEndEventListener(node, eventListener) {\n if (endEvents.length === 0) {\n window.setTimeout(eventListener, 0);\n return;\n }\n endEvents.forEach(function (endEvent) {\n addEventListener(node, endEvent, eventListener);\n });\n },\n removeEndEventListener: function removeEndEventListener(node, eventListener) {\n if (endEvents.length === 0) {\n return;\n }\n endEvents.forEach(function (endEvent) {\n removeEventListener(node, endEvent, eventListener);\n });\n }\n};\n\nexport default TransitionEvents;","import _typeof from 'babel-runtime/helpers/typeof';\nimport Event from './Event';\nimport classes from 'component-classes';\n\nvar isCssAnimationSupported = Event.endEvents.length !== 0;\nvar capitalPrefixes = ['Webkit', 'Moz', 'O',\n// ms is special .... !\n'ms'];\nvar prefixes = ['-webkit-', '-moz-', '-o-', 'ms-', ''];\n\nfunction getStyleProperty(node, name) {\n // old ff need null, https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle\n var style = window.getComputedStyle(node, null);\n var ret = '';\n for (var i = 0; i < prefixes.length; i++) {\n ret = style.getPropertyValue(prefixes[i] + name);\n if (ret) {\n break;\n }\n }\n return ret;\n}\n\nfunction fixBrowserByTimeout(node) {\n if (isCssAnimationSupported) {\n var transitionDelay = parseFloat(getStyleProperty(node, 'transition-delay')) || 0;\n var transitionDuration = parseFloat(getStyleProperty(node, 'transition-duration')) || 0;\n var animationDelay = parseFloat(getStyleProperty(node, 'animation-delay')) || 0;\n var animationDuration = parseFloat(getStyleProperty(node, 'animation-duration')) || 0;\n var time = Math.max(transitionDuration + transitionDelay, animationDuration + animationDelay);\n // sometimes, browser bug\n node.rcEndAnimTimeout = setTimeout(function () {\n node.rcEndAnimTimeout = null;\n if (node.rcEndListener) {\n node.rcEndListener();\n }\n }, time * 1000 + 200);\n }\n}\n\nfunction clearBrowserBugTimeout(node) {\n if (node.rcEndAnimTimeout) {\n clearTimeout(node.rcEndAnimTimeout);\n node.rcEndAnimTimeout = null;\n }\n}\n\nvar cssAnimation = function cssAnimation(node, transitionName, endCallback) {\n var nameIsObj = (typeof transitionName === 'undefined' ? 'undefined' : _typeof(transitionName)) === 'object';\n var className = nameIsObj ? transitionName.name : transitionName;\n var activeClassName = nameIsObj ? transitionName.active : transitionName + '-active';\n var end = endCallback;\n var start = void 0;\n var active = void 0;\n var nodeClasses = classes(node);\n\n if (endCallback && Object.prototype.toString.call(endCallback) === '[object Object]') {\n end = endCallback.end;\n start = endCallback.start;\n active = endCallback.active;\n }\n\n if (node.rcEndListener) {\n node.rcEndListener();\n }\n\n node.rcEndListener = function (e) {\n if (e && e.target !== node) {\n return;\n }\n\n if (node.rcAnimTimeout) {\n clearTimeout(node.rcAnimTimeout);\n node.rcAnimTimeout = null;\n }\n\n clearBrowserBugTimeout(node);\n\n nodeClasses.remove(className);\n nodeClasses.remove(activeClassName);\n\n Event.removeEndEventListener(node, node.rcEndListener);\n node.rcEndListener = null;\n\n // Usually this optional end is used for informing an owner of\n // a leave animation and telling it to remove the child.\n if (end) {\n end();\n }\n };\n\n Event.addEndEventListener(node, node.rcEndListener);\n\n if (start) {\n start();\n }\n nodeClasses.add(className);\n\n node.rcAnimTimeout = setTimeout(function () {\n node.rcAnimTimeout = null;\n nodeClasses.add(activeClassName);\n if (active) {\n setTimeout(active, 0);\n }\n fixBrowserByTimeout(node);\n // 30ms for firefox\n }, 30);\n\n return {\n stop: function stop() {\n if (node.rcEndListener) {\n node.rcEndListener();\n }\n }\n };\n};\n\ncssAnimation.style = function (node, style, callback) {\n if (node.rcEndListener) {\n node.rcEndListener();\n }\n\n node.rcEndListener = function (e) {\n if (e && e.target !== node) {\n return;\n }\n\n if (node.rcAnimTimeout) {\n clearTimeout(node.rcAnimTimeout);\n node.rcAnimTimeout = null;\n }\n\n clearBrowserBugTimeout(node);\n\n Event.removeEndEventListener(node, node.rcEndListener);\n node.rcEndListener = null;\n\n // Usually this optional callback is used for informing an owner of\n // a leave animation and telling it to remove the child.\n if (callback) {\n callback();\n }\n };\n\n Event.addEndEventListener(node, node.rcEndListener);\n\n node.rcAnimTimeout = setTimeout(function () {\n for (var s in style) {\n if (style.hasOwnProperty(s)) {\n node.style[s] = style[s];\n }\n }\n node.rcAnimTimeout = null;\n fixBrowserByTimeout(node);\n }, 0);\n};\n\ncssAnimation.setTransition = function (node, p, value) {\n var property = p;\n var v = value;\n if (value === undefined) {\n v = property;\n property = '';\n }\n property = property || '';\n capitalPrefixes.forEach(function (prefix) {\n node.style[prefix + 'Transition' + property] = v;\n });\n};\n\ncssAnimation.isCssAnimationSupported = isCssAnimationSupported;\n\nexport { isCssAnimationSupported };\n\nexport default cssAnimation;","var util = {\n isAppearSupported: function isAppearSupported(props) {\n return props.transitionName && props.transitionAppear || props.animation.appear;\n },\n isEnterSupported: function isEnterSupported(props) {\n return props.transitionName && props.transitionEnter || props.animation.enter;\n },\n isLeaveSupported: function isLeaveSupported(props) {\n return props.transitionName && props.transitionLeave || props.animation.leave;\n },\n allowAppearCallback: function allowAppearCallback(props) {\n return props.transitionAppear || props.animation.appear;\n },\n allowEnterCallback: function allowEnterCallback(props) {\n return props.transitionEnter || props.animation.enter;\n },\n allowLeaveCallback: function allowLeaveCallback(props) {\n return props.transitionLeave || props.animation.leave;\n }\n};\nexport default util;","import _classCallCheck from 'babel-runtime/helpers/classCallCheck';\nimport _createClass from 'babel-runtime/helpers/createClass';\nimport _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';\nimport _inherits from 'babel-runtime/helpers/inherits';\nimport React from 'react';\nimport ReactDOM from 'react-dom';\nimport PropTypes from 'prop-types';\nimport cssAnimate, { isCssAnimationSupported } from 'css-animation';\nimport animUtil from './util/animate';\n\nvar transitionMap = {\n enter: 'transitionEnter',\n appear: 'transitionAppear',\n leave: 'transitionLeave'\n};\n\nvar AnimateChild = function (_React$Component) {\n _inherits(AnimateChild, _React$Component);\n\n function AnimateChild() {\n _classCallCheck(this, AnimateChild);\n\n return _possibleConstructorReturn(this, (AnimateChild.__proto__ || Object.getPrototypeOf(AnimateChild)).apply(this, arguments));\n }\n\n _createClass(AnimateChild, [{\n key: 'componentWillUnmount',\n value: function componentWillUnmount() {\n this.stop();\n }\n }, {\n key: 'componentWillEnter',\n value: function componentWillEnter(done) {\n if (animUtil.isEnterSupported(this.props)) {\n this.transition('enter', done);\n } else {\n done();\n }\n }\n }, {\n key: 'componentWillAppear',\n value: function componentWillAppear(done) {\n if (animUtil.isAppearSupported(this.props)) {\n this.transition('appear', done);\n } else {\n done();\n }\n }\n }, {\n key: 'componentWillLeave',\n value: function componentWillLeave(done) {\n if (animUtil.isLeaveSupported(this.props)) {\n this.transition('leave', done);\n } else {\n // always sync, do not interupt with react component life cycle\n // update hidden -> animate hidden ->\n // didUpdate -> animate leave -> unmount (if animate is none)\n done();\n }\n }\n }, {\n key: 'transition',\n value: function transition(animationType, finishCallback) {\n var _this2 = this;\n\n var node = ReactDOM.findDOMNode(this);\n var props = this.props;\n var transitionName = props.transitionName;\n var nameIsObj = typeof transitionName === 'object';\n this.stop();\n var end = function end() {\n _this2.stopper = null;\n finishCallback();\n };\n if ((isCssAnimationSupported || !props.animation[animationType]) && transitionName && props[transitionMap[animationType]]) {\n var name = nameIsObj ? transitionName[animationType] : transitionName + '-' + animationType;\n var activeName = name + '-active';\n if (nameIsObj && transitionName[animationType + 'Active']) {\n activeName = transitionName[animationType + 'Active'];\n }\n this.stopper = cssAnimate(node, {\n name: name,\n active: activeName\n }, end);\n } else {\n this.stopper = props.animation[animationType](node, end);\n }\n }\n }, {\n key: 'stop',\n value: function stop() {\n var stopper = this.stopper;\n if (stopper) {\n this.stopper = null;\n stopper.stop();\n }\n }\n }, {\n key: 'render',\n value: function render() {\n return this.props.children;\n }\n }]);\n\n return AnimateChild;\n}(React.Component);\n\nAnimateChild.propTypes = {\n children: PropTypes.any,\n animation: PropTypes.any,\n transitionName: PropTypes.any\n};\nexport default AnimateChild;","import _extends from 'babel-runtime/helpers/extends';\nimport _defineProperty from 'babel-runtime/helpers/defineProperty';\nimport _classCallCheck from 'babel-runtime/helpers/classCallCheck';\nimport _createClass from 'babel-runtime/helpers/createClass';\nimport _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';\nimport _inherits from 'babel-runtime/helpers/inherits';\nimport React from 'react';\nimport PropTypes from 'prop-types';\nimport unsafeLifecyclesPolyfill from 'rc-util/es/unsafeLifecyclesPolyfill';\nimport { toArrayChildren, mergeChildren, findShownChildInChildrenByKey, findChildInChildrenByKey, isSameChildren } from './ChildrenUtils';\nimport AnimateChild from './AnimateChild';\nimport animUtil from './util/animate';\n\nvar defaultKey = 'rc_animate_' + Date.now();\n\nfunction getChildrenFromProps(props) {\n var children = props.children;\n if (React.isValidElement(children)) {\n if (!children.key) {\n return React.cloneElement(children, {\n key: defaultKey\n });\n }\n }\n return children;\n}\n\nfunction noop() {}\n\nvar Animate = function (_React$Component) {\n _inherits(Animate, _React$Component);\n\n // eslint-disable-line\n\n function Animate(props) {\n _classCallCheck(this, Animate);\n\n var _this = _possibleConstructorReturn(this, (Animate.__proto__ || Object.getPrototypeOf(Animate)).call(this, props));\n\n _initialiseProps.call(_this);\n\n _this.currentlyAnimatingKeys = {};\n _this.keysToEnter = [];\n _this.keysToLeave = [];\n\n _this.state = {\n children: toArrayChildren(getChildrenFromProps(props))\n };\n\n _this.childrenRefs = {};\n return _this;\n }\n\n _createClass(Animate, [{\n key: 'componentDidMount',\n value: function componentDidMount() {\n var _this2 = this;\n\n var showProp = this.props.showProp;\n var children = this.state.children;\n if (showProp) {\n children = children.filter(function (child) {\n return !!child.props[showProp];\n });\n }\n children.forEach(function (child) {\n if (child) {\n _this2.performAppear(child.key);\n }\n });\n }\n }, {\n key: 'componentWillReceiveProps',\n value: function componentWillReceiveProps(nextProps) {\n var _this3 = this;\n\n this.nextProps = nextProps;\n var nextChildren = toArrayChildren(getChildrenFromProps(nextProps));\n var props = this.props;\n // exclusive needs immediate response\n if (props.exclusive) {\n Object.keys(this.currentlyAnimatingKeys).forEach(function (key) {\n _this3.stop(key);\n });\n }\n var showProp = props.showProp;\n var currentlyAnimatingKeys = this.currentlyAnimatingKeys;\n // last props children if exclusive\n var currentChildren = props.exclusive ? toArrayChildren(getChildrenFromProps(props)) : this.state.children;\n // in case destroy in showProp mode\n var newChildren = [];\n if (showProp) {\n currentChildren.forEach(function (currentChild) {\n var nextChild = currentChild && findChildInChildrenByKey(nextChildren, currentChild.key);\n var newChild = void 0;\n if ((!nextChild || !nextChild.props[showProp]) && currentChild.props[showProp]) {\n newChild = React.cloneElement(nextChild || currentChild, _defineProperty({}, showProp, true));\n } else {\n newChild = nextChild;\n }\n if (newChild) {\n newChildren.push(newChild);\n }\n });\n nextChildren.forEach(function (nextChild) {\n if (!nextChild || !findChildInChildrenByKey(currentChildren, nextChild.key)) {\n newChildren.push(nextChild);\n }\n });\n } else {\n newChildren = mergeChildren(currentChildren, nextChildren);\n }\n\n // need render to avoid update\n this.setState({\n children: newChildren\n });\n\n nextChildren.forEach(function (child) {\n var key = child && child.key;\n if (child && currentlyAnimatingKeys[key]) {\n return;\n }\n var hasPrev = child && findChildInChildrenByKey(currentChildren, key);\n if (showProp) {\n var showInNext = child.props[showProp];\n if (hasPrev) {\n var showInNow = findShownChildInChildrenByKey(currentChildren, key, showProp);\n if (!showInNow && showInNext) {\n _this3.keysToEnter.push(key);\n }\n } else if (showInNext) {\n _this3.keysToEnter.push(key);\n }\n } else if (!hasPrev) {\n _this3.keysToEnter.push(key);\n }\n });\n\n currentChildren.forEach(function (child) {\n var key = child && child.key;\n if (child && currentlyAnimatingKeys[key]) {\n return;\n }\n var hasNext = child && findChildInChildrenByKey(nextChildren, key);\n if (showProp) {\n var showInNow = child.props[showProp];\n if (hasNext) {\n var showInNext = findShownChildInChildrenByKey(nextChildren, key, showProp);\n if (!showInNext && showInNow) {\n _this3.keysToLeave.push(key);\n }\n } else if (showInNow) {\n _this3.keysToLeave.push(key);\n }\n } else if (!hasNext) {\n _this3.keysToLeave.push(key);\n }\n });\n }\n }, {\n key: 'componentDidUpdate',\n value: function componentDidUpdate() {\n var keysToEnter = this.keysToEnter;\n this.keysToEnter = [];\n keysToEnter.forEach(this.performEnter);\n var keysToLeave = this.keysToLeave;\n this.keysToLeave = [];\n keysToLeave.forEach(this.performLeave);\n }\n }, {\n key: 'isValidChildByKey',\n value: function isValidChildByKey(currentChildren, key) {\n var showProp = this.props.showProp;\n if (showProp) {\n return findShownChildInChildrenByKey(currentChildren, key, showProp);\n }\n return findChildInChildrenByKey(currentChildren, key);\n }\n }, {\n key: 'stop',\n value: function stop(key) {\n delete this.currentlyAnimatingKeys[key];\n var component = this.childrenRefs[key];\n if (component) {\n component.stop();\n }\n }\n }, {\n key: 'render',\n value: function render() {\n var _this4 = this;\n\n var props = this.props;\n this.nextProps = props;\n var stateChildren = this.state.children;\n var children = null;\n if (stateChildren) {\n children = stateChildren.map(function (child) {\n if (child === null || child === undefined) {\n return child;\n }\n if (!child.key) {\n throw new Error('must set key for children');\n }\n return React.createElement(\n AnimateChild,\n {\n key: child.key,\n ref: function ref(node) {\n _this4.childrenRefs[child.key] = node;\n },\n animation: props.animation,\n transitionName: props.transitionName,\n transitionEnter: props.transitionEnter,\n transitionAppear: props.transitionAppear,\n transitionLeave: props.transitionLeave\n },\n child\n );\n });\n }\n var Component = props.component;\n if (Component) {\n var passedProps = props;\n if (typeof Component === 'string') {\n passedProps = _extends({\n className: props.className,\n style: props.style\n }, props.componentProps);\n }\n return React.createElement(\n Component,\n passedProps,\n children\n );\n }\n return children[0] || null;\n }\n }]);\n\n return Animate;\n}(React.Component);\n\nAnimate.isAnimate = true;\nAnimate.propTypes = {\n className: PropTypes.string,\n style: PropTypes.object,\n component: PropTypes.any,\n componentProps: PropTypes.object,\n animation: PropTypes.object,\n transitionName: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),\n transitionEnter: PropTypes.bool,\n transitionAppear: PropTypes.bool,\n exclusive: PropTypes.bool,\n transitionLeave: PropTypes.bool,\n onEnd: PropTypes.func,\n onEnter: PropTypes.func,\n onLeave: PropTypes.func,\n onAppear: PropTypes.func,\n showProp: PropTypes.string,\n children: PropTypes.node\n};\nAnimate.defaultProps = {\n animation: {},\n component: 'span',\n componentProps: {},\n transitionEnter: true,\n transitionLeave: true,\n transitionAppear: false,\n onEnd: noop,\n onEnter: noop,\n onLeave: noop,\n onAppear: noop\n};\n\nvar _initialiseProps = function _initialiseProps() {\n var _this5 = this;\n\n this.performEnter = function (key) {\n // may already remove by exclusive\n if (_this5.childrenRefs[key]) {\n _this5.currentlyAnimatingKeys[key] = true;\n _this5.childrenRefs[key].componentWillEnter(_this5.handleDoneAdding.bind(_this5, key, 'enter'));\n }\n };\n\n this.performAppear = function (key) {\n if (_this5.childrenRefs[key]) {\n _this5.currentlyAnimatingKeys[key] = true;\n _this5.childrenRefs[key].componentWillAppear(_this5.handleDoneAdding.bind(_this5, key, 'appear'));\n }\n };\n\n this.handleDoneAdding = function (key, type) {\n var props = _this5.props;\n delete _this5.currentlyAnimatingKeys[key];\n // if update on exclusive mode, skip check\n if (props.exclusive && props !== _this5.nextProps) {\n return;\n }\n var currentChildren = toArrayChildren(getChildrenFromProps(props));\n if (!_this5.isValidChildByKey(currentChildren, key)) {\n // exclusive will not need this\n _this5.performLeave(key);\n } else if (type === 'appear') {\n if (animUtil.allowAppearCallback(props)) {\n props.onAppear(key);\n props.onEnd(key, true);\n }\n } else if (animUtil.allowEnterCallback(props)) {\n props.onEnter(key);\n props.onEnd(key, true);\n }\n };\n\n this.performLeave = function (key) {\n // may already remove by exclusive\n if (_this5.childrenRefs[key]) {\n _this5.currentlyAnimatingKeys[key] = true;\n _this5.childrenRefs[key].componentWillLeave(_this5.handleDoneLeaving.bind(_this5, key));\n }\n };\n\n this.handleDoneLeaving = function (key) {\n var props = _this5.props;\n delete _this5.currentlyAnimatingKeys[key];\n // if update on exclusive mode, skip check\n if (props.exclusive && props !== _this5.nextProps) {\n return;\n }\n var currentChildren = toArrayChildren(getChildrenFromProps(props));\n // in case state change is too fast\n if (_this5.isValidChildByKey(currentChildren, key)) {\n _this5.performEnter(key);\n } else {\n var end = function end() {\n if (animUtil.allowLeaveCallback(props)) {\n props.onLeave(key);\n props.onEnd(key, false);\n }\n };\n if (!isSameChildren(_this5.state.children, currentChildren, props.showProp)) {\n _this5.setState({\n children: currentChildren\n }, end);\n } else {\n end();\n }\n }\n };\n};\n\nexport default unsafeLifecyclesPolyfill(Animate);","import _objectWithoutProperties from 'babel-runtime/helpers/objectWithoutProperties';\nimport _classCallCheck from 'babel-runtime/helpers/classCallCheck';\nimport _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';\nimport _inherits from 'babel-runtime/helpers/inherits';\nimport React, { Component } from 'react';\nimport PropTypes from 'prop-types';\n\nvar LazyRenderBox = function (_Component) {\n _inherits(LazyRenderBox, _Component);\n\n function LazyRenderBox() {\n _classCallCheck(this, LazyRenderBox);\n\n return _possibleConstructorReturn(this, _Component.apply(this, arguments));\n }\n\n LazyRenderBox.prototype.shouldComponentUpdate = function shouldComponentUpdate(nextProps) {\n return nextProps.hiddenClassName || nextProps.visible;\n };\n\n LazyRenderBox.prototype.render = function render() {\n var _props = this.props,\n hiddenClassName = _props.hiddenClassName,\n visible = _props.visible,\n props = _objectWithoutProperties(_props, ['hiddenClassName', 'visible']);\n\n if (hiddenClassName || React.Children.count(props.children) > 1) {\n if (!visible && hiddenClassName) {\n props.className += ' ' + hiddenClassName;\n }\n return React.createElement('div', props);\n }\n\n return React.Children.only(props.children);\n };\n\n return LazyRenderBox;\n}(Component);\n\nLazyRenderBox.propTypes = {\n children: PropTypes.any,\n className: PropTypes.string,\n visible: PropTypes.bool,\n hiddenClassName: PropTypes.string\n};\n\n\nexport default LazyRenderBox;","import _classCallCheck from 'babel-runtime/helpers/classCallCheck';\nimport _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';\nimport _inherits from 'babel-runtime/helpers/inherits';\nimport React, { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport LazyRenderBox from './LazyRenderBox';\n\nvar PopupInner = function (_Component) {\n _inherits(PopupInner, _Component);\n\n function PopupInner() {\n _classCallCheck(this, PopupInner);\n\n return _possibleConstructorReturn(this, _Component.apply(this, arguments));\n }\n\n PopupInner.prototype.render = function render() {\n var props = this.props;\n var className = props.className;\n if (!props.visible) {\n className += ' ' + props.hiddenClassName;\n }\n return React.createElement(\n 'div',\n {\n className: className,\n onMouseEnter: props.onMouseEnter,\n onMouseLeave: props.onMouseLeave,\n onMouseDown: props.onMouseDown,\n onTouchStart: props.onTouchStart,\n style: props.style\n },\n React.createElement(\n LazyRenderBox,\n { className: props.prefixCls + '-content', visible: props.visible },\n props.children\n )\n );\n };\n\n return PopupInner;\n}(Component);\n\nPopupInner.propTypes = {\n hiddenClassName: PropTypes.string,\n className: PropTypes.string,\n prefixCls: PropTypes.string,\n onMouseEnter: PropTypes.func,\n onMouseLeave: PropTypes.func,\n onMouseDown: PropTypes.func,\n onTouchStart: PropTypes.func,\n children: PropTypes.any\n};\n\n\nexport default PopupInner;","import _extends from 'babel-runtime/helpers/extends';\nimport _classCallCheck from 'babel-runtime/helpers/classCallCheck';\nimport _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';\nimport _inherits from 'babel-runtime/helpers/inherits';\nimport React, { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport ReactDOM from 'react-dom';\nimport Align from 'rc-align';\nimport Animate from 'rc-animate';\nimport PopupInner from './PopupInner';\nimport LazyRenderBox from './LazyRenderBox';\nimport { saveRef } from './utils';\n\nvar Popup = function (_Component) {\n _inherits(Popup, _Component);\n\n function Popup(props) {\n _classCallCheck(this, Popup);\n\n var _this = _possibleConstructorReturn(this, _Component.call(this, props));\n\n _initialiseProps.call(_this);\n\n _this.state = {\n // Used for stretch\n stretchChecked: false,\n targetWidth: undefined,\n targetHeight: undefined\n };\n\n _this.savePopupRef = saveRef.bind(_this, 'popupInstance');\n _this.saveAlignRef = saveRef.bind(_this, 'alignInstance');\n return _this;\n }\n\n Popup.prototype.componentDidMount = function componentDidMount() {\n this.rootNode = this.getPopupDomNode();\n this.setStretchSize();\n };\n\n Popup.prototype.componentDidUpdate = function componentDidUpdate() {\n this.setStretchSize();\n };\n\n // Record size if stretch needed\n\n\n Popup.prototype.getPopupDomNode = function getPopupDomNode() {\n return ReactDOM.findDOMNode(this.popupInstance);\n };\n\n // `target` on `rc-align` can accept as a function to get the bind element or a point.\n // ref: https://www.npmjs.com/package/rc-align\n\n\n Popup.prototype.getMaskTransitionName = function getMaskTransitionName() {\n var props = this.props;\n var transitionName = props.maskTransitionName;\n var animation = props.maskAnimation;\n if (!transitionName && animation) {\n transitionName = props.prefixCls + '-' + animation;\n }\n return transitionName;\n };\n\n Popup.prototype.getTransitionName = function getTransitionName() {\n var props = this.props;\n var transitionName = props.transitionName;\n if (!transitionName && props.animation) {\n transitionName = props.prefixCls + '-' + props.animation;\n }\n return transitionName;\n };\n\n Popup.prototype.getClassName = function getClassName(currentAlignClassName) {\n return this.props.prefixCls + ' ' + this.props.className + ' ' + currentAlignClassName;\n };\n\n Popup.prototype.getPopupElement = function getPopupElement() {\n var _this2 = this;\n\n var savePopupRef = this.savePopupRef;\n var _state = this.state,\n stretchChecked = _state.stretchChecked,\n targetHeight = _state.targetHeight,\n targetWidth = _state.targetWidth;\n var _props = this.props,\n align = _props.align,\n visible = _props.visible,\n prefixCls = _props.prefixCls,\n style = _props.style,\n getClassNameFromAlign = _props.getClassNameFromAlign,\n destroyPopupOnHide = _props.destroyPopupOnHide,\n stretch = _props.stretch,\n children = _props.children,\n onMouseEnter = _props.onMouseEnter,\n onMouseLeave = _props.onMouseLeave,\n onMouseDown = _props.onMouseDown,\n onTouchStart = _props.onTouchStart;\n\n var className = this.getClassName(this.currentAlignClassName || getClassNameFromAlign(align));\n var hiddenClassName = prefixCls + '-hidden';\n\n if (!visible) {\n this.currentAlignClassName = null;\n }\n\n var sizeStyle = {};\n if (stretch) {\n // Stretch with target\n if (stretch.indexOf('height') !== -1) {\n sizeStyle.height = targetHeight;\n } else if (stretch.indexOf('minHeight') !== -1) {\n sizeStyle.minHeight = targetHeight;\n }\n if (stretch.indexOf('width') !== -1) {\n sizeStyle.width = targetWidth;\n } else if (stretch.indexOf('minWidth') !== -1) {\n sizeStyle.minWidth = targetWidth;\n }\n\n // Delay force align to makes ui smooth\n if (!stretchChecked) {\n sizeStyle.visibility = 'hidden';\n setTimeout(function () {\n if (_this2.alignInstance) {\n _this2.alignInstance.forceAlign();\n }\n }, 0);\n }\n }\n\n var newStyle = _extends({}, sizeStyle, style, this.getZIndexStyle());\n\n var popupInnerProps = {\n className: className,\n prefixCls: prefixCls,\n ref: savePopupRef,\n onMouseEnter: onMouseEnter,\n onMouseLeave: onMouseLeave,\n onMouseDown: onMouseDown,\n onTouchStart: onTouchStart,\n style: newStyle\n };\n if (destroyPopupOnHide) {\n return React.createElement(\n Animate,\n {\n component: '',\n exclusive: true,\n transitionAppear: true,\n transitionName: this.getTransitionName()\n },\n visible ? React.createElement(\n Align,\n {\n target: this.getAlignTarget(),\n key: 'popup',\n ref: this.saveAlignRef,\n monitorWindowResize: true,\n align: align,\n onAlign: this.onAlign\n },\n React.createElement(\n PopupInner,\n _extends({\n visible: true\n }, popupInnerProps),\n children\n )\n ) : null\n );\n }\n\n return React.createElement(\n Animate,\n {\n component: '',\n exclusive: true,\n transitionAppear: true,\n transitionName: this.getTransitionName(),\n showProp: 'xVisible'\n },\n React.createElement(\n Align,\n {\n target: this.getAlignTarget(),\n key: 'popup',\n ref: this.saveAlignRef,\n monitorWindowResize: true,\n xVisible: visible,\n childrenProps: { visible: 'xVisible' },\n disabled: !visible,\n align: align,\n onAlign: this.onAlign\n },\n React.createElement(\n PopupInner,\n _extends({\n hiddenClassName: hiddenClassName\n }, popupInnerProps),\n children\n )\n )\n );\n };\n\n Popup.prototype.getZIndexStyle = function getZIndexStyle() {\n var style = {};\n var props = this.props;\n if (props.zIndex !== undefined) {\n style.zIndex = props.zIndex;\n }\n return style;\n };\n\n Popup.prototype.getMaskElement = function getMaskElement() {\n var props = this.props;\n var maskElement = void 0;\n if (props.mask) {\n var maskTransition = this.getMaskTransitionName();\n maskElement = React.createElement(LazyRenderBox, {\n style: this.getZIndexStyle(),\n key: 'mask',\n className: props.prefixCls + '-mask',\n hiddenClassName: props.prefixCls + '-mask-hidden',\n visible: props.visible\n });\n if (maskTransition) {\n maskElement = React.createElement(\n Animate,\n {\n key: 'mask',\n showProp: 'visible',\n transitionAppear: true,\n component: '',\n transitionName: maskTransition\n },\n maskElement\n );\n }\n }\n return maskElement;\n };\n\n Popup.prototype.render = function render() {\n return React.createElement(\n 'div',\n null,\n this.getMaskElement(),\n this.getPopupElement()\n );\n };\n\n return Popup;\n}(Component);\n\nPopup.propTypes = {\n visible: PropTypes.bool,\n style: PropTypes.object,\n getClassNameFromAlign: PropTypes.func,\n onAlign: PropTypes.func,\n getRootDomNode: PropTypes.func,\n align: PropTypes.any,\n destroyPopupOnHide: PropTypes.bool,\n className: PropTypes.string,\n prefixCls: PropTypes.string,\n onMouseEnter: PropTypes.func,\n onMouseLeave: PropTypes.func,\n onMouseDown: PropTypes.func,\n onTouchStart: PropTypes.func,\n stretch: PropTypes.string,\n children: PropTypes.node,\n point: PropTypes.shape({\n pageX: PropTypes.number,\n pageY: PropTypes.number\n })\n};\n\nvar _initialiseProps = function _initialiseProps() {\n var _this3 = this;\n\n this.onAlign = function (popupDomNode, align) {\n var props = _this3.props;\n var currentAlignClassName = props.getClassNameFromAlign(align);\n // FIX: https://github.com/react-component/trigger/issues/56\n // FIX: https://github.com/react-component/tooltip/issues/79\n if (_this3.currentAlignClassName !== currentAlignClassName) {\n _this3.currentAlignClassName = currentAlignClassName;\n popupDomNode.className = _this3.getClassName(currentAlignClassName);\n }\n props.onAlign(popupDomNode, align);\n };\n\n this.setStretchSize = function () {\n var _props2 = _this3.props,\n stretch = _props2.stretch,\n getRootDomNode = _props2.getRootDomNode,\n visible = _props2.visible;\n var _state2 = _this3.state,\n stretchChecked = _state2.stretchChecked,\n targetHeight = _state2.targetHeight,\n targetWidth = _state2.targetWidth;\n\n\n if (!stretch || !visible) {\n if (stretchChecked) {\n _this3.setState({ stretchChecked: false });\n }\n return;\n }\n\n var $ele = getRootDomNode();\n if (!$ele) return;\n\n var height = $ele.offsetHeight;\n var width = $ele.offsetWidth;\n\n if (targetHeight !== height || targetWidth !== width || !stretchChecked) {\n _this3.setState({\n stretchChecked: true,\n targetHeight: height,\n targetWidth: width\n });\n }\n };\n\n this.getTargetElement = function () {\n return _this3.props.getRootDomNode();\n };\n\n this.getAlignTarget = function () {\n var point = _this3.props.point;\n\n if (point) {\n return point;\n }\n return _this3.getTargetElement;\n };\n};\n\nexport default Popup;","import _extends from 'babel-runtime/helpers/extends';\nimport _classCallCheck from 'babel-runtime/helpers/classCallCheck';\nimport _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';\nimport _inherits from 'babel-runtime/helpers/inherits';\nimport React from 'react';\nimport PropTypes from 'prop-types';\nimport { findDOMNode, createPortal } from 'react-dom';\nimport { polyfill } from 'react-lifecycles-compat';\nimport contains from 'rc-util/es/Dom/contains';\nimport addEventListener from 'rc-util/es/Dom/addEventListener';\nimport ContainerRender from 'rc-util/es/ContainerRender';\nimport Portal from 'rc-util/es/Portal';\nimport classNames from 'classnames';\n\nimport { getAlignFromPlacement, getAlignPopupClassName } from './utils';\nimport Popup from './Popup';\n\nfunction noop() {}\n\nfunction returnEmptyString() {\n return '';\n}\n\nfunction returnDocument() {\n return window.document;\n}\n\nvar ALL_HANDLERS = ['onClick', 'onMouseDown', 'onTouchStart', 'onMouseEnter', 'onMouseLeave', 'onFocus', 'onBlur', 'onContextMenu'];\n\nvar IS_REACT_16 = !!createPortal;\n\nvar contextTypes = {\n rcTrigger: PropTypes.shape({\n onPopupMouseDown: PropTypes.func\n })\n};\n\nvar Trigger = function (_React$Component) {\n _inherits(Trigger, _React$Component);\n\n function Trigger(props) {\n _classCallCheck(this, Trigger);\n\n var _this = _possibleConstructorReturn(this, _React$Component.call(this, props));\n\n _initialiseProps.call(_this);\n\n var popupVisible = void 0;\n if ('popupVisible' in props) {\n popupVisible = !!props.popupVisible;\n } else {\n popupVisible = !!props.defaultPopupVisible;\n }\n\n _this.state = {\n prevPopupVisible: popupVisible,\n popupVisible: popupVisible\n };\n\n ALL_HANDLERS.forEach(function (h) {\n _this['fire' + h] = function (e) {\n _this.fireEvents(h, e);\n };\n });\n return _this;\n }\n\n Trigger.prototype.getChildContext = function getChildContext() {\n return {\n rcTrigger: {\n onPopupMouseDown: this.onPopupMouseDown\n }\n };\n };\n\n Trigger.prototype.componentDidMount = function componentDidMount() {\n this.componentDidUpdate({}, {\n popupVisible: this.state.popupVisible\n });\n };\n\n Trigger.prototype.componentDidUpdate = function componentDidUpdate(_, prevState) {\n var props = this.props;\n var state = this.state;\n var triggerAfterPopupVisibleChange = function triggerAfterPopupVisibleChange() {\n if (prevState.popupVisible !== state.popupVisible) {\n props.afterPopupVisibleChange(state.popupVisible);\n }\n };\n if (!IS_REACT_16) {\n this.renderComponent(null, triggerAfterPopupVisibleChange);\n }\n\n // We must listen to `mousedown` or `touchstart`, edge case:\n // https://github.com/ant-design/ant-design/issues/5804\n // https://github.com/react-component/calendar/issues/250\n // https://github.com/react-component/trigger/issues/50\n if (state.popupVisible) {\n var currentDocument = void 0;\n if (!this.clickOutsideHandler && (this.isClickToHide() || this.isContextMenuToShow())) {\n currentDocument = props.getDocument();\n this.clickOutsideHandler = addEventListener(currentDocument, 'mousedown', this.onDocumentClick);\n }\n // always hide on mobile\n if (!this.touchOutsideHandler) {\n currentDocument = currentDocument || props.getDocument();\n this.touchOutsideHandler = addEventListener(currentDocument, 'touchstart', this.onDocumentClick);\n }\n // close popup when trigger type contains 'onContextMenu' and document is scrolling.\n if (!this.contextMenuOutsideHandler1 && this.isContextMenuToShow()) {\n currentDocument = currentDocument || props.getDocument();\n this.contextMenuOutsideHandler1 = addEventListener(currentDocument, 'scroll', this.onContextMenuClose);\n }\n // close popup when trigger type contains 'onContextMenu' and window is blur.\n if (!this.contextMenuOutsideHandler2 && this.isContextMenuToShow()) {\n this.contextMenuOutsideHandler2 = addEventListener(window, 'blur', this.onContextMenuClose);\n }\n return;\n }\n\n this.clearOutsideHandler();\n };\n\n Trigger.prototype.componentWillUnmount = function componentWillUnmount() {\n this.clearDelayTimer();\n this.clearOutsideHandler();\n clearTimeout(this.mouseDownTimeout);\n };\n\n Trigger.getDerivedStateFromProps = function getDerivedStateFromProps(_ref, prevState) {\n var popupVisible = _ref.popupVisible;\n\n var newState = {};\n\n if (popupVisible !== undefined && prevState.popupVisible !== popupVisible) {\n newState.popupVisible = popupVisible;\n newState.prevPopupVisible = prevState.popupVisible;\n }\n\n return newState;\n };\n\n Trigger.prototype.getPopupDomNode = function getPopupDomNode() {\n // for test\n if (this._component && this._component.getPopupDomNode) {\n return this._component.getPopupDomNode();\n }\n return null;\n };\n\n Trigger.prototype.getPopupAlign = function getPopupAlign() {\n var props = this.props;\n var popupPlacement = props.popupPlacement,\n popupAlign = props.popupAlign,\n builtinPlacements = props.builtinPlacements;\n\n if (popupPlacement && builtinPlacements) {\n return getAlignFromPlacement(builtinPlacements, popupPlacement, popupAlign);\n }\n return popupAlign;\n };\n\n /**\n * @param popupVisible Show or not the popup element\n * @param event SyntheticEvent, used for `pointAlign`\n */\n Trigger.prototype.setPopupVisible = function setPopupVisible(popupVisible, event) {\n var alignPoint = this.props.alignPoint;\n var prevPopupVisible = this.state.popupVisible;\n\n\n this.clearDelayTimer();\n\n if (prevPopupVisible !== popupVisible) {\n if (!('popupVisible' in this.props)) {\n this.setState({ popupVisible: popupVisible, prevPopupVisible: prevPopupVisible });\n }\n this.props.onPopupVisibleChange(popupVisible);\n }\n\n // Always record the point position since mouseEnterDelay will delay the show\n if (alignPoint && event) {\n this.setPoint(event);\n }\n };\n\n Trigger.prototype.delaySetPopupVisible = function delaySetPopupVisible(visible, delayS, event) {\n var _this2 = this;\n\n var delay = delayS * 1000;\n this.clearDelayTimer();\n if (delay) {\n var point = event ? { pageX: event.pageX, pageY: event.pageY } : null;\n this.delayTimer = setTimeout(function () {\n _this2.setPopupVisible(visible, point);\n _this2.clearDelayTimer();\n }, delay);\n } else {\n this.setPopupVisible(visible, event);\n }\n };\n\n Trigger.prototype.clearDelayTimer = function clearDelayTimer() {\n if (this.delayTimer) {\n clearTimeout(this.delayTimer);\n this.delayTimer = null;\n }\n };\n\n Trigger.prototype.clearOutsideHandler = function clearOutsideHandler() {\n if (this.clickOutsideHandler) {\n this.clickOutsideHandler.remove();\n this.clickOutsideHandler = null;\n }\n\n if (this.contextMenuOutsideHandler1) {\n this.contextMenuOutsideHandler1.remove();\n this.contextMenuOutsideHandler1 = null;\n }\n\n if (this.contextMenuOutsideHandler2) {\n this.contextMenuOutsideHandler2.remove();\n this.contextMenuOutsideHandler2 = null;\n }\n\n if (this.touchOutsideHandler) {\n this.touchOutsideHandler.remove();\n this.touchOutsideHandler = null;\n }\n };\n\n Trigger.prototype.createTwoChains = function createTwoChains(event) {\n var childPros = this.props.children.props;\n var props = this.props;\n if (childPros[event] && props[event]) {\n return this['fire' + event];\n }\n return childPros[event] || props[event];\n };\n\n Trigger.prototype.isClickToShow = function isClickToShow() {\n var _props = this.props,\n action = _props.action,\n showAction = _props.showAction;\n\n return action.indexOf('click') !== -1 || showAction.indexOf('click') !== -1;\n };\n\n Trigger.prototype.isContextMenuToShow = function isContextMenuToShow() {\n var _props2 = this.props,\n action = _props2.action,\n showAction = _props2.showAction;\n\n return action.indexOf('contextMenu') !== -1 || showAction.indexOf('contextMenu') !== -1;\n };\n\n Trigger.prototype.isClickToHide = function isClickToHide() {\n var _props3 = this.props,\n action = _props3.action,\n hideAction = _props3.hideAction;\n\n return action.indexOf('click') !== -1 || hideAction.indexOf('click') !== -1;\n };\n\n Trigger.prototype.isMouseEnterToShow = function isMouseEnterToShow() {\n var _props4 = this.props,\n action = _props4.action,\n showAction = _props4.showAction;\n\n return action.indexOf('hover') !== -1 || showAction.indexOf('mouseEnter') !== -1;\n };\n\n Trigger.prototype.isMouseLeaveToHide = function isMouseLeaveToHide() {\n var _props5 = this.props,\n action = _props5.action,\n hideAction = _props5.hideAction;\n\n return action.indexOf('hover') !== -1 || hideAction.indexOf('mouseLeave') !== -1;\n };\n\n Trigger.prototype.isFocusToShow = function isFocusToShow() {\n var _props6 = this.props,\n action = _props6.action,\n showAction = _props6.showAction;\n\n return action.indexOf('focus') !== -1 || showAction.indexOf('focus') !== -1;\n };\n\n Trigger.prototype.isBlurToHide = function isBlurToHide() {\n var _props7 = this.props,\n action = _props7.action,\n hideAction = _props7.hideAction;\n\n return action.indexOf('focus') !== -1 || hideAction.indexOf('blur') !== -1;\n };\n\n Trigger.prototype.forcePopupAlign = function forcePopupAlign() {\n if (this.state.popupVisible && this._component && this._component.alignInstance) {\n this._component.alignInstance.forceAlign();\n }\n };\n\n Trigger.prototype.fireEvents = function fireEvents(type, e) {\n var childCallback = this.props.children.props[type];\n if (childCallback) {\n childCallback(e);\n }\n var callback = this.props[type];\n if (callback) {\n callback(e);\n }\n };\n\n Trigger.prototype.close = function close() {\n this.setPopupVisible(false);\n };\n\n Trigger.prototype.render = function render() {\n var _this3 = this;\n\n var popupVisible = this.state.popupVisible;\n var _props8 = this.props,\n children = _props8.children,\n forceRender = _props8.forceRender,\n alignPoint = _props8.alignPoint,\n className = _props8.className;\n\n var child = React.Children.only(children);\n var newChildProps = { key: 'trigger' };\n\n if (this.isContextMenuToShow()) {\n newChildProps.onContextMenu = this.onContextMenu;\n } else {\n newChildProps.onContextMenu = this.createTwoChains('onContextMenu');\n }\n\n if (this.isClickToHide() || this.isClickToShow()) {\n newChildProps.onClick = this.onClick;\n newChildProps.onMouseDown = this.onMouseDown;\n newChildProps.onTouchStart = this.onTouchStart;\n } else {\n newChildProps.onClick = this.createTwoChains('onClick');\n newChildProps.onMouseDown = this.createTwoChains('onMouseDown');\n newChildProps.onTouchStart = this.createTwoChains('onTouchStart');\n }\n if (this.isMouseEnterToShow()) {\n newChildProps.onMouseEnter = this.onMouseEnter;\n if (alignPoint) {\n newChildProps.onMouseMove = this.onMouseMove;\n }\n } else {\n newChildProps.onMouseEnter = this.createTwoChains('onMouseEnter');\n }\n if (this.isMouseLeaveToHide()) {\n newChildProps.onMouseLeave = this.onMouseLeave;\n } else {\n newChildProps.onMouseLeave = this.createTwoChains('onMouseLeave');\n }\n if (this.isFocusToShow() || this.isBlurToHide()) {\n newChildProps.onFocus = this.onFocus;\n newChildProps.onBlur = this.onBlur;\n } else {\n newChildProps.onFocus = this.createTwoChains('onFocus');\n newChildProps.onBlur = this.createTwoChains('onBlur');\n }\n\n var childrenClassName = classNames(child && child.props && child.props.className, className);\n if (childrenClassName) {\n newChildProps.className = childrenClassName;\n }\n var trigger = React.cloneElement(child, newChildProps);\n\n if (!IS_REACT_16) {\n return React.createElement(\n ContainerRender,\n {\n parent: this,\n visible: popupVisible,\n autoMount: false,\n forceRender: forceRender,\n getComponent: this.getComponent,\n getContainer: this.getContainer\n },\n function (_ref2) {\n var renderComponent = _ref2.renderComponent;\n\n _this3.renderComponent = renderComponent;\n return trigger;\n }\n );\n }\n\n var portal = void 0;\n // prevent unmounting after it's rendered\n if (popupVisible || this._component || forceRender) {\n portal = React.createElement(\n Portal,\n { key: 'portal', getContainer: this.getContainer, didUpdate: this.handlePortalUpdate },\n this.getComponent()\n );\n }\n\n return [trigger, portal];\n };\n\n return Trigger;\n}(React.Component);\n\nTrigger.propTypes = {\n children: PropTypes.any,\n action: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]),\n showAction: PropTypes.any,\n hideAction: PropTypes.any,\n getPopupClassNameFromAlign: PropTypes.any,\n onPopupVisibleChange: PropTypes.func,\n afterPopupVisibleChange: PropTypes.func,\n popup: PropTypes.oneOfType([PropTypes.node, PropTypes.func]).isRequired,\n popupStyle: PropTypes.object,\n prefixCls: PropTypes.string,\n popupClassName: PropTypes.string,\n className: PropTypes.string,\n popupPlacement: PropTypes.string,\n builtinPlacements: PropTypes.object,\n popupTransitionName: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),\n popupAnimation: PropTypes.any,\n mouseEnterDelay: PropTypes.number,\n mouseLeaveDelay: PropTypes.number,\n zIndex: PropTypes.number,\n focusDelay: PropTypes.number,\n blurDelay: PropTypes.number,\n getPopupContainer: PropTypes.func,\n getDocument: PropTypes.func,\n forceRender: PropTypes.bool,\n destroyPopupOnHide: PropTypes.bool,\n mask: PropTypes.bool,\n maskClosable: PropTypes.bool,\n onPopupAlign: PropTypes.func,\n popupAlign: PropTypes.object,\n popupVisible: PropTypes.bool,\n defaultPopupVisible: PropTypes.bool,\n maskTransitionName: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),\n maskAnimation: PropTypes.string,\n stretch: PropTypes.string,\n alignPoint: PropTypes.bool // Maybe we can support user pass position in the future\n};\nTrigger.contextTypes = contextTypes;\nTrigger.childContextTypes = contextTypes;\nTrigger.defaultProps = {\n prefixCls: 'rc-trigger-popup',\n getPopupClassNameFromAlign: returnEmptyString,\n getDocument: returnDocument,\n onPopupVisibleChange: noop,\n afterPopupVisibleChange: noop,\n onPopupAlign: noop,\n popupClassName: '',\n mouseEnterDelay: 0,\n mouseLeaveDelay: 0.1,\n focusDelay: 0,\n blurDelay: 0.15,\n popupStyle: {},\n destroyPopupOnHide: false,\n popupAlign: {},\n defaultPopupVisible: false,\n mask: false,\n maskClosable: true,\n action: [],\n showAction: [],\n hideAction: []\n};\n\nvar _initialiseProps = function _initialiseProps() {\n var _this4 = this;\n\n this.onMouseEnter = function (e) {\n var mouseEnterDelay = _this4.props.mouseEnterDelay;\n\n _this4.fireEvents('onMouseEnter', e);\n _this4.delaySetPopupVisible(true, mouseEnterDelay, mouseEnterDelay ? null : e);\n };\n\n this.onMouseMove = function (e) {\n _this4.fireEvents('onMouseMove', e);\n _this4.setPoint(e);\n };\n\n this.onMouseLeave = function (e) {\n _this4.fireEvents('onMouseLeave', e);\n _this4.delaySetPopupVisible(false, _this4.props.mouseLeaveDelay);\n };\n\n this.onPopupMouseEnter = function () {\n _this4.clearDelayTimer();\n };\n\n this.onPopupMouseLeave = function (e) {\n // https://github.com/react-component/trigger/pull/13\n // react bug?\n if (e.relatedTarget && !e.relatedTarget.setTimeout && _this4._component && _this4._component.getPopupDomNode && contains(_this4._component.getPopupDomNode(), e.relatedTarget)) {\n return;\n }\n _this4.delaySetPopupVisible(false, _this4.props.mouseLeaveDelay);\n };\n\n this.onFocus = function (e) {\n _this4.fireEvents('onFocus', e);\n // incase focusin and focusout\n _this4.clearDelayTimer();\n if (_this4.isFocusToShow()) {\n _this4.focusTime = Date.now();\n _this4.delaySetPopupVisible(true, _this4.props.focusDelay);\n }\n };\n\n this.onMouseDown = function (e) {\n _this4.fireEvents('onMouseDown', e);\n _this4.preClickTime = Date.now();\n };\n\n this.onTouchStart = function (e) {\n _this4.fireEvents('onTouchStart', e);\n _this4.preTouchTime = Date.now();\n };\n\n this.onBlur = function (e) {\n _this4.fireEvents('onBlur', e);\n _this4.clearDelayTimer();\n if (_this4.isBlurToHide()) {\n _this4.delaySetPopupVisible(false, _this4.props.blurDelay);\n }\n };\n\n this.onContextMenu = function (e) {\n e.preventDefault();\n _this4.fireEvents('onContextMenu', e);\n _this4.setPopupVisible(true, e);\n };\n\n this.onContextMenuClose = function () {\n if (_this4.isContextMenuToShow()) {\n _this4.close();\n }\n };\n\n this.onClick = function (event) {\n _this4.fireEvents('onClick', event);\n // focus will trigger click\n if (_this4.focusTime) {\n var preTime = void 0;\n if (_this4.preClickTime && _this4.preTouchTime) {\n preTime = Math.min(_this4.preClickTime, _this4.preTouchTime);\n } else if (_this4.preClickTime) {\n preTime = _this4.preClickTime;\n } else if (_this4.preTouchTime) {\n preTime = _this4.preTouchTime;\n }\n if (Math.abs(preTime - _this4.focusTime) < 20) {\n return;\n }\n _this4.focusTime = 0;\n }\n _this4.preClickTime = 0;\n _this4.preTouchTime = 0;\n\n // Only prevent default when all the action is click.\n // https://github.com/ant-design/ant-design/issues/17043\n // https://github.com/ant-design/ant-design/issues/17291\n if (_this4.isClickToShow() && (_this4.isClickToHide() || _this4.isBlurToHide()) && event && event.preventDefault) {\n event.preventDefault();\n }\n var nextVisible = !_this4.state.popupVisible;\n if (_this4.isClickToHide() && !nextVisible || nextVisible && _this4.isClickToShow()) {\n _this4.setPopupVisible(!_this4.state.popupVisible, event);\n }\n };\n\n this.onPopupMouseDown = function () {\n var _context$rcTrigger = _this4.context.rcTrigger,\n rcTrigger = _context$rcTrigger === undefined ? {} : _context$rcTrigger;\n\n _this4.hasPopupMouseDown = true;\n\n clearTimeout(_this4.mouseDownTimeout);\n _this4.mouseDownTimeout = setTimeout(function () {\n _this4.hasPopupMouseDown = false;\n }, 0);\n\n if (rcTrigger.onPopupMouseDown) {\n rcTrigger.onPopupMouseDown.apply(rcTrigger, arguments);\n }\n };\n\n this.onDocumentClick = function (event) {\n if (_this4.props.mask && !_this4.props.maskClosable) {\n return;\n }\n\n var target = event.target;\n var root = findDOMNode(_this4);\n if (!contains(root, target) && !_this4.hasPopupMouseDown) {\n _this4.close();\n }\n };\n\n this.getRootDomNode = function () {\n return findDOMNode(_this4);\n };\n\n this.getPopupClassNameFromAlign = function (align) {\n var className = [];\n var _props9 = _this4.props,\n popupPlacement = _props9.popupPlacement,\n builtinPlacements = _props9.builtinPlacements,\n prefixCls = _props9.prefixCls,\n alignPoint = _props9.alignPoint,\n getPopupClassNameFromAlign = _props9.getPopupClassNameFromAlign;\n\n if (popupPlacement && builtinPlacements) {\n className.push(getAlignPopupClassName(builtinPlacements, prefixCls, align, alignPoint));\n }\n if (getPopupClassNameFromAlign) {\n className.push(getPopupClassNameFromAlign(align));\n }\n return className.join(' ');\n };\n\n this.getComponent = function () {\n var _props10 = _this4.props,\n prefixCls = _props10.prefixCls,\n destroyPopupOnHide = _props10.destroyPopupOnHide,\n popupClassName = _props10.popupClassName,\n action = _props10.action,\n onPopupAlign = _props10.onPopupAlign,\n popupAnimation = _props10.popupAnimation,\n popupTransitionName = _props10.popupTransitionName,\n popupStyle = _props10.popupStyle,\n mask = _props10.mask,\n maskAnimation = _props10.maskAnimation,\n maskTransitionName = _props10.maskTransitionName,\n zIndex = _props10.zIndex,\n popup = _props10.popup,\n stretch = _props10.stretch,\n alignPoint = _props10.alignPoint;\n var _state = _this4.state,\n popupVisible = _state.popupVisible,\n point = _state.point;\n\n\n var align = _this4.getPopupAlign();\n\n var mouseProps = {};\n if (_this4.isMouseEnterToShow()) {\n mouseProps.onMouseEnter = _this4.onPopupMouseEnter;\n }\n if (_this4.isMouseLeaveToHide()) {\n mouseProps.onMouseLeave = _this4.onPopupMouseLeave;\n }\n\n mouseProps.onMouseDown = _this4.onPopupMouseDown;\n mouseProps.onTouchStart = _this4.onPopupMouseDown;\n\n return React.createElement(\n Popup,\n _extends({\n prefixCls: prefixCls,\n destroyPopupOnHide: destroyPopupOnHide,\n visible: popupVisible,\n point: alignPoint && point,\n className: popupClassName,\n action: action,\n align: align,\n onAlign: onPopupAlign,\n animation: popupAnimation,\n getClassNameFromAlign: _this4.getPopupClassNameFromAlign\n }, mouseProps, {\n stretch: stretch,\n getRootDomNode: _this4.getRootDomNode,\n style: popupStyle,\n mask: mask,\n zIndex: zIndex,\n transitionName: popupTransitionName,\n maskAnimation: maskAnimation,\n maskTransitionName: maskTransitionName,\n ref: _this4.savePopup\n }),\n typeof popup === 'function' ? popup() : popup\n );\n };\n\n this.getContainer = function () {\n var props = _this4.props;\n\n var popupContainer = document.createElement('div');\n // Make sure default popup container will never cause scrollbar appearing\n // https://github.com/react-component/trigger/issues/41\n popupContainer.style.position = 'absolute';\n popupContainer.style.top = '0';\n popupContainer.style.left = '0';\n popupContainer.style.width = '100%';\n var mountNode = props.getPopupContainer ? props.getPopupContainer(findDOMNode(_this4)) : props.getDocument().body;\n mountNode.appendChild(popupContainer);\n return popupContainer;\n };\n\n this.setPoint = function (point) {\n var alignPoint = _this4.props.alignPoint;\n\n if (!alignPoint || !point) return;\n\n _this4.setState({\n point: {\n pageX: point.pageX,\n pageY: point.pageY\n }\n });\n };\n\n this.handlePortalUpdate = function () {\n if (_this4.state.prevPopupVisible !== _this4.state.popupVisible) {\n _this4.props.afterPopupVisibleChange(_this4.state.popupVisible);\n }\n };\n\n this.savePopup = function (node) {\n _this4._component = node;\n };\n};\n\npolyfill(Trigger);\n\nexport default Trigger;","var canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement);\n\n// ================= Transition =================\n// Event wrapper. Copy from react source code\nfunction makePrefixMap(styleProp, eventName) {\n var prefixes = {};\n\n prefixes[styleProp.toLowerCase()] = eventName.toLowerCase();\n prefixes['Webkit' + styleProp] = 'webkit' + eventName;\n prefixes['Moz' + styleProp] = 'moz' + eventName;\n prefixes['ms' + styleProp] = 'MS' + eventName;\n prefixes['O' + styleProp] = 'o' + eventName.toLowerCase();\n\n return prefixes;\n}\n\nexport function getVendorPrefixes(domSupport, win) {\n var prefixes = {\n animationend: makePrefixMap('Animation', 'AnimationEnd'),\n transitionend: makePrefixMap('Transition', 'TransitionEnd')\n };\n\n if (domSupport) {\n if (!('AnimationEvent' in win)) {\n delete prefixes.animationend.animation;\n }\n\n if (!('TransitionEvent' in win)) {\n delete prefixes.transitionend.transition;\n }\n }\n\n return prefixes;\n}\n\nvar vendorPrefixes = getVendorPrefixes(canUseDOM, typeof window !== 'undefined' ? window : {});\n\nvar style = {};\n\nif (canUseDOM) {\n style = document.createElement('div').style;\n}\n\nvar prefixedEventNames = {};\n\nexport function getVendorPrefixedEventName(eventName) {\n if (prefixedEventNames[eventName]) {\n return prefixedEventNames[eventName];\n }\n\n var prefixMap = vendorPrefixes[eventName];\n\n if (prefixMap) {\n var stylePropList = Object.keys(prefixMap);\n var len = stylePropList.length;\n for (var i = 0; i < len; i += 1) {\n var styleProp = stylePropList[i];\n if (Object.prototype.hasOwnProperty.call(prefixMap, styleProp) && styleProp in style) {\n prefixedEventNames[eventName] = prefixMap[styleProp];\n return prefixedEventNames[eventName];\n }\n }\n }\n\n return '';\n}\n\nexport var animationEndName = getVendorPrefixedEventName('animationend');\nexport var transitionEndName = getVendorPrefixedEventName('transitionend');\nexport var supportTransition = !!(animationEndName && transitionEndName);\n\nexport function getTransitionName(transitionName, transitionType) {\n if (!transitionName) return null;\n\n if (typeof transitionName === 'object') {\n var type = transitionType.replace(/-\\w/g, function (match) {\n return match[1].toUpperCase();\n });\n return transitionName[type];\n }\n\n return transitionName + '-' + transitionType;\n}","import _defineProperty from 'babel-runtime/helpers/defineProperty';\nimport _extends from 'babel-runtime/helpers/extends';\nimport _classCallCheck from 'babel-runtime/helpers/classCallCheck';\nimport _createClass from 'babel-runtime/helpers/createClass';\nimport _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';\nimport _inherits from 'babel-runtime/helpers/inherits';\n/* eslint-disable react/default-props-match-prop-types, react/no-multi-comp */\nimport React from 'react';\nimport PropTypes from 'prop-types';\nimport { polyfill } from 'react-lifecycles-compat';\nimport findDOMNode from 'rc-util/es/Dom/findDOMNode';\nimport classNames from 'classnames';\nimport raf from 'raf';\nimport { getTransitionName, animationEndName, transitionEndName, supportTransition } from './util/motion';\n\nvar STATUS_NONE = 'none';\nvar STATUS_APPEAR = 'appear';\nvar STATUS_ENTER = 'enter';\nvar STATUS_LEAVE = 'leave';\n\nexport var MotionPropTypes = {\n eventProps: PropTypes.object, // Internal usage. Only pass by CSSMotionList\n visible: PropTypes.bool,\n children: PropTypes.func,\n motionName: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),\n motionAppear: PropTypes.bool,\n motionEnter: PropTypes.bool,\n motionLeave: PropTypes.bool,\n motionLeaveImmediately: PropTypes.bool, // Trigger leave motion immediately\n removeOnLeave: PropTypes.bool,\n leavedClassName: PropTypes.string,\n onAppearStart: PropTypes.func,\n onAppearActive: PropTypes.func,\n onAppearEnd: PropTypes.func,\n onEnterStart: PropTypes.func,\n onEnterActive: PropTypes.func,\n onEnterEnd: PropTypes.func,\n onLeaveStart: PropTypes.func,\n onLeaveActive: PropTypes.func,\n onLeaveEnd: PropTypes.func\n};\n\n/**\n * `transitionSupport` is used for none transition test case.\n * Default we use browser transition event support check.\n */\nexport function genCSSMotion(config) {\n var transitionSupport = config;\n var forwardRef = !!React.forwardRef;\n\n if (typeof config === 'object') {\n transitionSupport = config.transitionSupport;\n forwardRef = 'forwardRef' in config ? config.forwardRef : forwardRef;\n }\n\n function isSupportTransition(props) {\n return !!(props.motionName && transitionSupport);\n }\n\n var CSSMotion = function (_React$Component) {\n _inherits(CSSMotion, _React$Component);\n\n function CSSMotion() {\n _classCallCheck(this, CSSMotion);\n\n var _this = _possibleConstructorReturn(this, (CSSMotion.__proto__ || Object.getPrototypeOf(CSSMotion)).call(this));\n\n _this.onDomUpdate = function () {\n var _this$state = _this.state,\n status = _this$state.status,\n newStatus = _this$state.newStatus;\n var _this$props = _this.props,\n onAppearStart = _this$props.onAppearStart,\n onEnterStart = _this$props.onEnterStart,\n onLeaveStart = _this$props.onLeaveStart,\n onAppearActive = _this$props.onAppearActive,\n onEnterActive = _this$props.onEnterActive,\n onLeaveActive = _this$props.onLeaveActive,\n motionAppear = _this$props.motionAppear,\n motionEnter = _this$props.motionEnter,\n motionLeave = _this$props.motionLeave;\n\n\n if (!isSupportTransition(_this.props)) {\n return;\n }\n\n // Event injection\n var $ele = _this.getElement();\n if (_this.$cacheEle !== $ele) {\n _this.removeEventListener(_this.$cacheEle);\n _this.addEventListener($ele);\n _this.$cacheEle = $ele;\n }\n\n // Init status\n if (newStatus && status === STATUS_APPEAR && motionAppear) {\n _this.updateStatus(onAppearStart, null, null, function () {\n _this.updateActiveStatus(onAppearActive, STATUS_APPEAR);\n });\n } else if (newStatus && status === STATUS_ENTER && motionEnter) {\n _this.updateStatus(onEnterStart, null, null, function () {\n _this.updateActiveStatus(onEnterActive, STATUS_ENTER);\n });\n } else if (newStatus && status === STATUS_LEAVE && motionLeave) {\n _this.updateStatus(onLeaveStart, null, null, function () {\n _this.updateActiveStatus(onLeaveActive, STATUS_LEAVE);\n });\n }\n };\n\n _this.onMotionEnd = function (event) {\n var _this$state2 = _this.state,\n status = _this$state2.status,\n statusActive = _this$state2.statusActive;\n var _this$props2 = _this.props,\n onAppearEnd = _this$props2.onAppearEnd,\n onEnterEnd = _this$props2.onEnterEnd,\n onLeaveEnd = _this$props2.onLeaveEnd;\n\n if (status === STATUS_APPEAR && statusActive) {\n _this.updateStatus(onAppearEnd, { status: STATUS_NONE }, event);\n } else if (status === STATUS_ENTER && statusActive) {\n _this.updateStatus(onEnterEnd, { status: STATUS_NONE }, event);\n } else if (status === STATUS_LEAVE && statusActive) {\n _this.updateStatus(onLeaveEnd, { status: STATUS_NONE }, event);\n }\n };\n\n _this.setNodeRef = function (node) {\n var internalRef = _this.props.internalRef;\n\n _this.node = node;\n\n if (typeof internalRef === 'function') {\n internalRef(node);\n } else if (internalRef && 'current' in internalRef) {\n internalRef.current = node;\n }\n };\n\n _this.getElement = function () {\n return findDOMNode(_this.node || _this);\n };\n\n _this.addEventListener = function ($ele) {\n if (!$ele) return;\n\n $ele.addEventListener(transitionEndName, _this.onMotionEnd);\n $ele.addEventListener(animationEndName, _this.onMotionEnd);\n };\n\n _this.removeEventListener = function ($ele) {\n if (!$ele) return;\n\n $ele.removeEventListener(transitionEndName, _this.onMotionEnd);\n $ele.removeEventListener(animationEndName, _this.onMotionEnd);\n };\n\n _this.updateStatus = function (styleFunc, additionalState, event, callback) {\n var statusStyle = styleFunc ? styleFunc(_this.getElement(), event) : null;\n\n if (statusStyle === false || _this._destroyed) return;\n\n var nextStep = void 0;\n if (callback) {\n nextStep = function nextStep() {\n _this.nextFrame(callback);\n };\n }\n\n _this.setState(_extends({\n statusStyle: typeof statusStyle === 'object' ? statusStyle : null,\n newStatus: false\n }, additionalState), nextStep); // Trigger before next frame & after `componentDidMount`\n };\n\n _this.updateActiveStatus = function (styleFunc, currentStatus) {\n // `setState` use `postMessage` to trigger at the end of frame.\n // Let's use requestAnimationFrame to update new state in next frame.\n _this.nextFrame(function () {\n var status = _this.state.status;\n\n if (status !== currentStatus) return;\n\n _this.updateStatus(styleFunc, { statusActive: true });\n });\n };\n\n _this.nextFrame = function (func) {\n _this.cancelNextFrame();\n _this.raf = raf(func);\n };\n\n _this.cancelNextFrame = function () {\n if (_this.raf) {\n raf.cancel(_this.raf);\n _this.raf = null;\n }\n };\n\n _this.state = {\n status: STATUS_NONE,\n statusActive: false,\n newStatus: false,\n statusStyle: null\n };\n _this.$cacheEle = null;\n _this.node = null;\n _this.raf = null;\n return _this;\n }\n\n _createClass(CSSMotion, [{\n key: 'componentDidMount',\n value: function componentDidMount() {\n this.onDomUpdate();\n }\n }, {\n key: 'componentDidUpdate',\n value: function componentDidUpdate() {\n this.onDomUpdate();\n }\n }, {\n key: 'componentWillUnmount',\n value: function componentWillUnmount() {\n this._destroyed = true;\n this.removeEventListener(this.$cacheEle);\n this.cancelNextFrame();\n }\n }, {\n key: 'render',\n value: function render() {\n var _classNames;\n\n var _state = this.state,\n status = _state.status,\n statusActive = _state.statusActive,\n statusStyle = _state.statusStyle;\n var _props = this.props,\n children = _props.children,\n motionName = _props.motionName,\n visible = _props.visible,\n removeOnLeave = _props.removeOnLeave,\n leavedClassName = _props.leavedClassName,\n eventProps = _props.eventProps;\n\n\n if (!children) return null;\n\n if (status === STATUS_NONE || !isSupportTransition(this.props)) {\n if (visible) {\n return children(_extends({}, eventProps), this.setNodeRef);\n } else if (!removeOnLeave) {\n return children(_extends({}, eventProps, { className: leavedClassName }), this.setNodeRef);\n }\n\n return null;\n }\n\n return children(_extends({}, eventProps, {\n className: classNames((_classNames = {}, _defineProperty(_classNames, getTransitionName(motionName, status), status !== STATUS_NONE), _defineProperty(_classNames, getTransitionName(motionName, status + '-active'), status !== STATUS_NONE && statusActive), _defineProperty(_classNames, motionName, typeof motionName === 'string'), _classNames)),\n style: statusStyle\n }), this.setNodeRef);\n }\n }], [{\n key: 'getDerivedStateFromProps',\n value: function getDerivedStateFromProps(props, _ref) {\n var prevProps = _ref.prevProps,\n prevStatus = _ref.status;\n\n if (!isSupportTransition(props)) return {};\n\n var visible = props.visible,\n motionAppear = props.motionAppear,\n motionEnter = props.motionEnter,\n motionLeave = props.motionLeave,\n motionLeaveImmediately = props.motionLeaveImmediately;\n\n var newState = {\n prevProps: props\n };\n\n // Clean up status if prop set to false\n if (prevStatus === STATUS_APPEAR && !motionAppear || prevStatus === STATUS_ENTER && !motionEnter || prevStatus === STATUS_LEAVE && !motionLeave) {\n newState.status = STATUS_NONE;\n newState.statusActive = false;\n newState.newStatus = false;\n }\n\n // Appear\n if (!prevProps && visible && motionAppear) {\n newState.status = STATUS_APPEAR;\n newState.statusActive = false;\n newState.newStatus = true;\n }\n\n // Enter\n if (prevProps && !prevProps.visible && visible && motionEnter) {\n newState.status = STATUS_ENTER;\n newState.statusActive = false;\n newState.newStatus = true;\n }\n\n // Leave\n if (prevProps && prevProps.visible && !visible && motionLeave || !prevProps && motionLeaveImmediately && !visible && motionLeave) {\n newState.status = STATUS_LEAVE;\n newState.statusActive = false;\n newState.newStatus = true;\n }\n\n return newState;\n }\n }]);\n\n return CSSMotion;\n }(React.Component);\n\n CSSMotion.propTypes = _extends({}, MotionPropTypes, {\n\n internalRef: PropTypes.oneOfType([PropTypes.object, PropTypes.func])\n });\n CSSMotion.defaultProps = {\n visible: true,\n motionEnter: true,\n motionAppear: true,\n motionLeave: true,\n removeOnLeave: true\n };\n\n\n polyfill(CSSMotion);\n\n if (!forwardRef) {\n return CSSMotion;\n }\n\n return React.forwardRef(function (props, ref) {\n return React.createElement(CSSMotion, _extends({ internalRef: ref }, props));\n });\n}\n\nexport default genCSSMotion(supportTransition);","import ReactDOM from 'react-dom';\n/**\n * Return if a node is a DOM node. Else will return by `findDOMNode`\n */\n\nexport default function findDOMNode(node) {\n if (node instanceof HTMLElement) {\n return node;\n }\n\n return ReactDOM.findDOMNode(node);\n}","var autoAdjustOverflow = {\n adjustX: 1,\n adjustY: 1\n};\nexport var placements = {\n topLeft: {\n points: ['bl', 'tl'],\n overflow: autoAdjustOverflow,\n offset: [0, -7]\n },\n bottomLeft: {\n points: ['tl', 'bl'],\n overflow: autoAdjustOverflow,\n offset: [0, 7]\n },\n leftTop: {\n points: ['tr', 'tl'],\n overflow: autoAdjustOverflow,\n offset: [-4, 0]\n },\n rightTop: {\n points: ['tl', 'tr'],\n overflow: autoAdjustOverflow,\n offset: [4, 0]\n }\n};\nexport default placements;","function _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nimport * as React from 'react';\nimport * as ReactDOM from 'react-dom';\nimport Trigger from 'rc-trigger';\nimport KeyCode from \"rc-util/es/KeyCode\"; // import Animate from 'rc-animate';\n\nimport CSSMotion from \"rc-animate/es/CSSMotion\";\nimport classNames from 'classnames';\nimport { connect } from 'mini-store';\nimport SubPopupMenu from './SubPopupMenu';\nimport placements from './placements';\nimport { noop, loopMenuItemRecursively, getMenuIdFromSubMenuEventKey, menuAllProps } from './util';\nvar guid = 0;\nvar popupPlacementMap = {\n horizontal: 'bottomLeft',\n vertical: 'rightTop',\n 'vertical-left': 'rightTop',\n 'vertical-right': 'leftTop'\n};\n\nvar updateDefaultActiveFirst = function updateDefaultActiveFirst(store, eventKey, defaultActiveFirst) {\n var menuId = getMenuIdFromSubMenuEventKey(eventKey);\n var state = store.getState();\n store.setState({\n defaultActiveFirst: _objectSpread({}, state.defaultActiveFirst, _defineProperty({}, menuId, defaultActiveFirst))\n });\n};\n\nexport var SubMenu =\n/*#__PURE__*/\nfunction (_React$Component) {\n _inherits(SubMenu, _React$Component);\n\n function SubMenu(props) {\n var _this;\n\n _classCallCheck(this, SubMenu);\n\n _this = _possibleConstructorReturn(this, _getPrototypeOf(SubMenu).call(this, props));\n\n _this.onDestroy = function (key) {\n _this.props.onDestroy(key);\n };\n /**\n * note:\n * This legacy code that `onKeyDown` is called by parent instead of dom self.\n * which need return code to check if this event is handled\n */\n\n\n _this.onKeyDown = function (e) {\n var keyCode = e.keyCode;\n var menu = _this.menuInstance;\n var _this$props = _this.props,\n isOpen = _this$props.isOpen,\n store = _this$props.store;\n\n if (keyCode === KeyCode.ENTER) {\n _this.onTitleClick(e);\n\n updateDefaultActiveFirst(store, _this.props.eventKey, true);\n return true;\n }\n\n if (keyCode === KeyCode.RIGHT) {\n if (isOpen) {\n menu.onKeyDown(e);\n } else {\n _this.triggerOpenChange(true); // need to update current menu's defaultActiveFirst value\n\n\n updateDefaultActiveFirst(store, _this.props.eventKey, true);\n }\n\n return true;\n }\n\n if (keyCode === KeyCode.LEFT) {\n var handled;\n\n if (isOpen) {\n handled = menu.onKeyDown(e);\n } else {\n return undefined;\n }\n\n if (!handled) {\n _this.triggerOpenChange(false);\n\n handled = true;\n }\n\n return handled;\n }\n\n if (isOpen && (keyCode === KeyCode.UP || keyCode === KeyCode.DOWN)) {\n return menu.onKeyDown(e);\n }\n\n return undefined;\n };\n\n _this.onOpenChange = function (e) {\n _this.props.onOpenChange(e);\n };\n\n _this.onPopupVisibleChange = function (visible) {\n _this.triggerOpenChange(visible, visible ? 'mouseenter' : 'mouseleave');\n };\n\n _this.onMouseEnter = function (e) {\n var _this$props2 = _this.props,\n key = _this$props2.eventKey,\n onMouseEnter = _this$props2.onMouseEnter,\n store = _this$props2.store;\n updateDefaultActiveFirst(store, _this.props.eventKey, false);\n onMouseEnter({\n key: key,\n domEvent: e\n });\n };\n\n _this.onMouseLeave = function (e) {\n var _this$props3 = _this.props,\n parentMenu = _this$props3.parentMenu,\n eventKey = _this$props3.eventKey,\n onMouseLeave = _this$props3.onMouseLeave;\n parentMenu.subMenuInstance = _assertThisInitialized(_this);\n onMouseLeave({\n key: eventKey,\n domEvent: e\n });\n };\n\n _this.onTitleMouseEnter = function (domEvent) {\n var _this$props4 = _this.props,\n key = _this$props4.eventKey,\n onItemHover = _this$props4.onItemHover,\n onTitleMouseEnter = _this$props4.onTitleMouseEnter;\n onItemHover({\n key: key,\n hover: true\n });\n onTitleMouseEnter({\n key: key,\n domEvent: domEvent\n });\n };\n\n _this.onTitleMouseLeave = function (e) {\n var _this$props5 = _this.props,\n parentMenu = _this$props5.parentMenu,\n eventKey = _this$props5.eventKey,\n onItemHover = _this$props5.onItemHover,\n onTitleMouseLeave = _this$props5.onTitleMouseLeave;\n parentMenu.subMenuInstance = _assertThisInitialized(_this);\n onItemHover({\n key: eventKey,\n hover: false\n });\n onTitleMouseLeave({\n key: eventKey,\n domEvent: e\n });\n };\n\n _this.onTitleClick = function (e) {\n var _assertThisInitialize = _assertThisInitialized(_this),\n props = _assertThisInitialize.props;\n\n props.onTitleClick({\n key: props.eventKey,\n domEvent: e\n });\n\n if (props.triggerSubMenuAction === 'hover') {\n return;\n }\n\n _this.triggerOpenChange(!props.isOpen, 'click');\n\n updateDefaultActiveFirst(props.store, _this.props.eventKey, false);\n };\n\n _this.onSubMenuClick = function (info) {\n // in the case of overflowed submenu\n // onClick is not copied over\n if (typeof _this.props.onClick === 'function') {\n _this.props.onClick(_this.addKeyPath(info));\n }\n };\n\n _this.onSelect = function (info) {\n _this.props.onSelect(info);\n };\n\n _this.onDeselect = function (info) {\n _this.props.onDeselect(info);\n };\n\n _this.getPrefixCls = function () {\n return \"\".concat(_this.props.rootPrefixCls, \"-submenu\");\n };\n\n _this.getActiveClassName = function () {\n return \"\".concat(_this.getPrefixCls(), \"-active\");\n };\n\n _this.getDisabledClassName = function () {\n return \"\".concat(_this.getPrefixCls(), \"-disabled\");\n };\n\n _this.getSelectedClassName = function () {\n return \"\".concat(_this.getPrefixCls(), \"-selected\");\n };\n\n _this.getOpenClassName = function () {\n return \"\".concat(_this.props.rootPrefixCls, \"-submenu-open\");\n };\n\n _this.saveMenuInstance = function (c) {\n // children menu instance\n _this.menuInstance = c;\n };\n\n _this.addKeyPath = function (info) {\n return _objectSpread({}, info, {\n keyPath: (info.keyPath || []).concat(_this.props.eventKey)\n });\n };\n\n _this.triggerOpenChange = function (open, type) {\n var key = _this.props.eventKey;\n\n var openChange = function openChange() {\n _this.onOpenChange({\n key: key,\n item: _assertThisInitialized(_this),\n trigger: type,\n open: open\n });\n };\n\n if (type === 'mouseenter') {\n // make sure mouseenter happen after other menu item's mouseleave\n _this.mouseenterTimeout = setTimeout(function () {\n openChange();\n }, 0);\n } else {\n openChange();\n }\n };\n\n _this.isChildrenSelected = function () {\n var ret = {\n find: false\n };\n loopMenuItemRecursively(_this.props.children, _this.props.selectedKeys, ret);\n return ret.find;\n };\n\n _this.isOpen = function () {\n return _this.props.openKeys.indexOf(_this.props.eventKey) !== -1;\n };\n\n _this.adjustWidth = function () {\n /* istanbul ignore if */\n if (!_this.subMenuTitle || !_this.menuInstance) {\n return;\n }\n\n var popupMenu = ReactDOM.findDOMNode(_this.menuInstance);\n\n if (popupMenu.offsetWidth >= _this.subMenuTitle.offsetWidth) {\n return;\n }\n /* istanbul ignore next */\n\n\n popupMenu.style.minWidth = \"\".concat(_this.subMenuTitle.offsetWidth, \"px\");\n };\n\n _this.saveSubMenuTitle = function (subMenuTitle) {\n _this.subMenuTitle = subMenuTitle;\n };\n\n var store = props.store,\n eventKey = props.eventKey;\n\n var _store$getState = store.getState(),\n defaultActiveFirst = _store$getState.defaultActiveFirst;\n\n _this.isRootMenu = false;\n var value = false;\n\n if (defaultActiveFirst) {\n value = defaultActiveFirst[eventKey];\n }\n\n updateDefaultActiveFirst(store, eventKey, value);\n return _this;\n }\n\n _createClass(SubMenu, [{\n key: \"componentDidMount\",\n value: function componentDidMount() {\n this.componentDidUpdate();\n }\n }, {\n key: \"componentDidUpdate\",\n value: function componentDidUpdate() {\n var _this2 = this;\n\n var _this$props6 = this.props,\n mode = _this$props6.mode,\n parentMenu = _this$props6.parentMenu,\n manualRef = _this$props6.manualRef; // invoke customized ref to expose component to mixin\n\n if (manualRef) {\n manualRef(this);\n }\n\n if (mode !== 'horizontal' || !parentMenu.isRootMenu || !this.props.isOpen) {\n return;\n }\n\n this.minWidthTimeout = setTimeout(function () {\n return _this2.adjustWidth();\n }, 0);\n }\n }, {\n key: \"componentWillUnmount\",\n value: function componentWillUnmount() {\n var _this$props7 = this.props,\n onDestroy = _this$props7.onDestroy,\n eventKey = _this$props7.eventKey;\n\n if (onDestroy) {\n onDestroy(eventKey);\n }\n /* istanbul ignore if */\n\n\n if (this.minWidthTimeout) {\n clearTimeout(this.minWidthTimeout);\n }\n /* istanbul ignore if */\n\n\n if (this.mouseenterTimeout) {\n clearTimeout(this.mouseenterTimeout);\n }\n }\n }, {\n key: \"renderChildren\",\n value: function renderChildren(children) {\n var _this3 = this;\n\n var props = this.props;\n var baseProps = {\n mode: props.mode === 'horizontal' ? 'vertical' : props.mode,\n visible: this.props.isOpen,\n level: props.level + 1,\n inlineIndent: props.inlineIndent,\n focusable: false,\n onClick: this.onSubMenuClick,\n onSelect: this.onSelect,\n onDeselect: this.onDeselect,\n onDestroy: this.onDestroy,\n selectedKeys: props.selectedKeys,\n eventKey: \"\".concat(props.eventKey, \"-menu-\"),\n openKeys: props.openKeys,\n motion: props.motion,\n onOpenChange: this.onOpenChange,\n subMenuOpenDelay: props.subMenuOpenDelay,\n parentMenu: this,\n subMenuCloseDelay: props.subMenuCloseDelay,\n forceSubMenuRender: props.forceSubMenuRender,\n triggerSubMenuAction: props.triggerSubMenuAction,\n builtinPlacements: props.builtinPlacements,\n defaultActiveFirst: props.store.getState().defaultActiveFirst[getMenuIdFromSubMenuEventKey(props.eventKey)],\n multiple: props.multiple,\n prefixCls: props.rootPrefixCls,\n id: this.internalMenuId,\n manualRef: this.saveMenuInstance,\n itemIcon: props.itemIcon,\n expandIcon: props.expandIcon\n };\n var haveRendered = this.haveRendered;\n this.haveRendered = true;\n this.haveOpened = this.haveOpened || baseProps.visible || baseProps.forceSubMenuRender; // never rendered not planning to, don't render\n\n if (!this.haveOpened) {\n return React.createElement(\"div\", null);\n } // ================== Motion ==================\n // don't show transition on first rendering (no animation for opened menu)\n // show appear transition if it's not visible (not sure why)\n // show appear transition if it's not inline mode\n\n\n var mergedMotion = _objectSpread({}, props.motion, {\n leavedClassName: \"\".concat(props.rootPrefixCls, \"-hidden\"),\n removeOnLeave: false,\n motionAppear: haveRendered || !baseProps.visible || baseProps.mode !== 'inline'\n });\n\n return React.createElement(CSSMotion, Object.assign({\n visible: baseProps.visible\n }, mergedMotion), function (_ref) {\n var className = _ref.className,\n style = _ref.style;\n var mergedClassName = classNames(\"\".concat(baseProps.prefixCls, \"-sub\"), className);\n return React.createElement(SubPopupMenu, Object.assign({}, baseProps, {\n id: _this3.internalMenuId,\n className: mergedClassName,\n style: style\n }), children);\n });\n }\n }, {\n key: \"render\",\n value: function render() {\n var _classNames;\n\n var props = _objectSpread({}, this.props);\n\n var isOpen = props.isOpen;\n var prefixCls = this.getPrefixCls();\n var isInlineMode = props.mode === 'inline';\n var className = classNames(prefixCls, \"\".concat(prefixCls, \"-\").concat(props.mode), (_classNames = {}, _defineProperty(_classNames, props.className, !!props.className), _defineProperty(_classNames, this.getOpenClassName(), isOpen), _defineProperty(_classNames, this.getActiveClassName(), props.active || isOpen && !isInlineMode), _defineProperty(_classNames, this.getDisabledClassName(), props.disabled), _defineProperty(_classNames, this.getSelectedClassName(), this.isChildrenSelected()), _classNames));\n\n if (!this.internalMenuId) {\n if (props.eventKey) {\n this.internalMenuId = \"\".concat(props.eventKey, \"$Menu\");\n } else {\n guid += 1;\n this.internalMenuId = \"$__$\".concat(guid, \"$Menu\");\n }\n }\n\n var mouseEvents = {};\n var titleClickEvents = {};\n var titleMouseEvents = {};\n\n if (!props.disabled) {\n mouseEvents = {\n onMouseLeave: this.onMouseLeave,\n onMouseEnter: this.onMouseEnter\n }; // only works in title, not outer li\n\n titleClickEvents = {\n onClick: this.onTitleClick\n };\n titleMouseEvents = {\n onMouseEnter: this.onTitleMouseEnter,\n onMouseLeave: this.onTitleMouseLeave\n };\n }\n\n var style = {};\n\n if (isInlineMode) {\n style.paddingLeft = props.inlineIndent * props.level;\n }\n\n var ariaOwns = {}; // only set aria-owns when menu is open\n // otherwise it would be an invalid aria-owns value\n // since corresponding node cannot be found\n\n if (this.props.isOpen) {\n ariaOwns = {\n 'aria-owns': this.internalMenuId\n };\n } // expand custom icon should NOT be displayed in menu with horizontal mode.\n\n\n var icon = null;\n\n if (props.mode !== 'horizontal') {\n icon = this.props.expandIcon; // ReactNode\n\n if (typeof this.props.expandIcon === 'function') {\n icon = React.createElement(this.props.expandIcon, _objectSpread({}, this.props));\n }\n }\n\n var title = React.createElement(\"div\", Object.assign({\n ref: this.saveSubMenuTitle,\n style: style,\n className: \"\".concat(prefixCls, \"-title\")\n }, titleMouseEvents, titleClickEvents, {\n \"aria-expanded\": isOpen\n }, ariaOwns, {\n \"aria-haspopup\": \"true\",\n title: typeof props.title === 'string' ? props.title : undefined\n }), props.title, icon || React.createElement(\"i\", {\n className: \"\".concat(prefixCls, \"-arrow\")\n }));\n var children = this.renderChildren(props.children);\n var getPopupContainer = props.parentMenu.isRootMenu ? props.parentMenu.props.getPopupContainer : function (triggerNode) {\n return triggerNode.parentNode;\n };\n var popupPlacement = popupPlacementMap[props.mode];\n var popupAlign = props.popupOffset ? {\n offset: props.popupOffset\n } : {};\n var popupClassName = props.mode === 'inline' ? '' : props.popupClassName;\n var disabled = props.disabled,\n triggerSubMenuAction = props.triggerSubMenuAction,\n subMenuOpenDelay = props.subMenuOpenDelay,\n forceSubMenuRender = props.forceSubMenuRender,\n subMenuCloseDelay = props.subMenuCloseDelay,\n builtinPlacements = props.builtinPlacements;\n menuAllProps.forEach(function (key) {\n return delete props[key];\n }); // Set onClick to null, to ignore propagated onClick event\n\n delete props.onClick;\n return React.createElement(\"li\", Object.assign({}, props, mouseEvents, {\n className: className,\n role: \"menuitem\"\n }), isInlineMode && title, isInlineMode && children, !isInlineMode && React.createElement(Trigger, {\n prefixCls: prefixCls,\n popupClassName: \"\".concat(prefixCls, \"-popup \").concat(popupClassName),\n getPopupContainer: getPopupContainer,\n builtinPlacements: Object.assign({}, placements, builtinPlacements),\n popupPlacement: popupPlacement,\n popupVisible: isOpen,\n popupAlign: popupAlign,\n popup: children,\n action: disabled ? [] : [triggerSubMenuAction],\n mouseEnterDelay: subMenuOpenDelay,\n mouseLeaveDelay: subMenuCloseDelay,\n onPopupVisibleChange: this.onPopupVisibleChange,\n forceRender: forceSubMenuRender\n }, title));\n }\n }]);\n\n return SubMenu;\n}(React.Component);\nSubMenu.defaultProps = {\n onMouseEnter: noop,\n onMouseLeave: noop,\n onTitleMouseEnter: noop,\n onTitleMouseLeave: noop,\n onTitleClick: noop,\n manualRef: noop,\n mode: 'vertical',\n title: ''\n};\nvar connected = connect(function (_ref2, _ref3) {\n var openKeys = _ref2.openKeys,\n activeKey = _ref2.activeKey,\n selectedKeys = _ref2.selectedKeys;\n var eventKey = _ref3.eventKey,\n subMenuKey = _ref3.subMenuKey;\n return {\n isOpen: openKeys.indexOf(eventKey) > -1,\n active: activeKey[subMenuKey] === eventKey,\n selectedKeys: selectedKeys\n };\n})(SubMenu);\nconnected.isSubMenu = true;\nexport default connected;","function _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }\n\nfunction _nonIterableSpread() { throw new TypeError(\"Invalid attempt to spread non-iterable instance\"); }\n\nfunction _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === \"[object Arguments]\") return Array.from(iter); }\n\nfunction _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }\n\nfunction ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nimport * as React from 'react';\nimport * as ReactDOM from 'react-dom';\nimport ResizeObserver from 'resize-observer-polyfill';\nimport SubMenu from './SubMenu';\nimport { getWidth, setStyle, menuAllProps } from './util';\nvar canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement);\nvar MENUITEM_OVERFLOWED_CLASSNAME = 'menuitem-overflowed';\nvar FLOAT_PRECISION_ADJUST = 0.5; // Fix ssr\n\nif (canUseDOM) {\n // eslint-disable-next-line global-require\n require('mutationobserver-shim');\n}\n\nvar DOMWrap =\n/*#__PURE__*/\nfunction (_React$Component) {\n _inherits(DOMWrap, _React$Component);\n\n function DOMWrap() {\n var _this;\n\n _classCallCheck(this, DOMWrap);\n\n _this = _possibleConstructorReturn(this, _getPrototypeOf(DOMWrap).apply(this, arguments));\n _this.resizeObserver = null;\n _this.mutationObserver = null; // original scroll size of the list\n\n _this.originalTotalWidth = 0; // copy of overflowed items\n\n _this.overflowedItems = []; // cache item of the original items (so we can track the size and order)\n\n _this.menuItemSizes = [];\n _this.state = {\n lastVisibleIndex: undefined\n }; // get all valid menuItem nodes\n\n _this.getMenuItemNodes = function () {\n var prefixCls = _this.props.prefixCls;\n var ul = ReactDOM.findDOMNode(_assertThisInitialized(_this));\n\n if (!ul) {\n return [];\n } // filter out all overflowed indicator placeholder\n\n\n return [].slice.call(ul.children).filter(function (node) {\n return node.className.split(' ').indexOf(\"\".concat(prefixCls, \"-overflowed-submenu\")) < 0;\n });\n };\n\n _this.getOverflowedSubMenuItem = function (keyPrefix, overflowedItems, renderPlaceholder) {\n var _this$props = _this.props,\n overflowedIndicator = _this$props.overflowedIndicator,\n level = _this$props.level,\n mode = _this$props.mode,\n prefixCls = _this$props.prefixCls,\n theme = _this$props.theme;\n\n if (level !== 1 || mode !== 'horizontal') {\n return null;\n } // put all the overflowed item inside a submenu\n // with a title of overflow indicator ('...')\n\n\n var copy = _this.props.children[0];\n\n var _copy$props = copy.props,\n throwAway = _copy$props.children,\n title = _copy$props.title,\n propStyle = _copy$props.style,\n rest = _objectWithoutProperties(_copy$props, [\"children\", \"title\", \"style\"]);\n\n var style = _objectSpread({}, propStyle);\n\n var key = \"\".concat(keyPrefix, \"-overflowed-indicator\");\n var eventKey = \"\".concat(keyPrefix, \"-overflowed-indicator\");\n\n if (overflowedItems.length === 0 && renderPlaceholder !== true) {\n style = _objectSpread({}, style, {\n display: 'none'\n });\n } else if (renderPlaceholder) {\n style = _objectSpread({}, style, {\n visibility: 'hidden',\n // prevent from taking normal dom space\n position: 'absolute'\n });\n key = \"\".concat(key, \"-placeholder\");\n eventKey = \"\".concat(eventKey, \"-placeholder\");\n }\n\n var popupClassName = theme ? \"\".concat(prefixCls, \"-\").concat(theme) : '';\n var props = {};\n menuAllProps.forEach(function (k) {\n if (rest[k] !== undefined) {\n props[k] = rest[k];\n }\n });\n return React.createElement(SubMenu, Object.assign({\n title: overflowedIndicator,\n className: \"\".concat(prefixCls, \"-overflowed-submenu\"),\n popupClassName: popupClassName\n }, props, {\n key: key,\n eventKey: eventKey,\n disabled: false,\n style: style\n }), overflowedItems);\n }; // memorize rendered menuSize\n\n\n _this.setChildrenWidthAndResize = function () {\n if (_this.props.mode !== 'horizontal') {\n return;\n }\n\n var ul = ReactDOM.findDOMNode(_assertThisInitialized(_this));\n\n if (!ul) {\n return;\n }\n\n var ulChildrenNodes = ul.children;\n\n if (!ulChildrenNodes || ulChildrenNodes.length === 0) {\n return;\n }\n\n var lastOverflowedIndicatorPlaceholder = ul.children[ulChildrenNodes.length - 1]; // need last overflowed indicator for calculating length;\n\n setStyle(lastOverflowedIndicatorPlaceholder, 'display', 'inline-block');\n\n var menuItemNodes = _this.getMenuItemNodes(); // reset display attribute for all hidden elements caused by overflow to calculate updated width\n // and then reset to original state after width calculation\n\n\n var overflowedItems = menuItemNodes.filter(function (c) {\n return c.className.split(' ').indexOf(MENUITEM_OVERFLOWED_CLASSNAME) >= 0;\n });\n overflowedItems.forEach(function (c) {\n setStyle(c, 'display', 'inline-block');\n });\n _this.menuItemSizes = menuItemNodes.map(function (c) {\n return getWidth(c);\n });\n overflowedItems.forEach(function (c) {\n setStyle(c, 'display', 'none');\n });\n _this.overflowedIndicatorWidth = getWidth(ul.children[ul.children.length - 1]);\n _this.originalTotalWidth = _this.menuItemSizes.reduce(function (acc, cur) {\n return acc + cur;\n }, 0);\n\n _this.handleResize(); // prevent the overflowed indicator from taking space;\n\n\n setStyle(lastOverflowedIndicatorPlaceholder, 'display', 'none');\n };\n\n _this.handleResize = function () {\n if (_this.props.mode !== 'horizontal') {\n return;\n }\n\n var ul = ReactDOM.findDOMNode(_assertThisInitialized(_this));\n\n if (!ul) {\n return;\n }\n\n var width = getWidth(ul);\n _this.overflowedItems = [];\n var currentSumWidth = 0; // index for last visible child in horizontal mode\n\n var lastVisibleIndex; // float number comparison could be problematic\n // e.g. 0.1 + 0.2 > 0.3 =====> true\n // thus using FLOAT_PRECISION_ADJUST as buffer to help the situation\n\n if (_this.originalTotalWidth > width + FLOAT_PRECISION_ADJUST) {\n lastVisibleIndex = -1;\n\n _this.menuItemSizes.forEach(function (liWidth) {\n currentSumWidth += liWidth;\n\n if (currentSumWidth + _this.overflowedIndicatorWidth <= width) {\n lastVisibleIndex += 1;\n }\n });\n }\n\n _this.setState({\n lastVisibleIndex: lastVisibleIndex\n });\n };\n\n return _this;\n }\n\n _createClass(DOMWrap, [{\n key: \"componentDidMount\",\n value: function componentDidMount() {\n var _this2 = this;\n\n this.setChildrenWidthAndResize();\n\n if (this.props.level === 1 && this.props.mode === 'horizontal') {\n var menuUl = ReactDOM.findDOMNode(this);\n\n if (!menuUl) {\n return;\n }\n\n this.resizeObserver = new ResizeObserver(function (entries) {\n entries.forEach(_this2.setChildrenWidthAndResize);\n });\n [].slice.call(menuUl.children).concat(menuUl).forEach(function (el) {\n _this2.resizeObserver.observe(el);\n });\n\n if (typeof MutationObserver !== 'undefined') {\n this.mutationObserver = new MutationObserver(function () {\n _this2.resizeObserver.disconnect();\n\n [].slice.call(menuUl.children).concat(menuUl).forEach(function (el) {\n _this2.resizeObserver.observe(el);\n });\n\n _this2.setChildrenWidthAndResize();\n });\n this.mutationObserver.observe(menuUl, {\n attributes: false,\n childList: true,\n subTree: false\n });\n }\n }\n }\n }, {\n key: \"componentWillUnmount\",\n value: function componentWillUnmount() {\n if (this.resizeObserver) {\n this.resizeObserver.disconnect();\n }\n\n if (this.mutationObserver) {\n this.resizeObserver.disconnect();\n }\n }\n }, {\n key: \"renderChildren\",\n value: function renderChildren(children) {\n var _this3 = this;\n\n // need to take care of overflowed items in horizontal mode\n var lastVisibleIndex = this.state.lastVisibleIndex;\n return (children || []).reduce(function (acc, childNode, index) {\n var item = childNode;\n\n if (_this3.props.mode === 'horizontal') {\n var overflowed = _this3.getOverflowedSubMenuItem(childNode.props.eventKey, []);\n\n if (lastVisibleIndex !== undefined && _this3.props.className.indexOf(\"\".concat(_this3.props.prefixCls, \"-root\")) !== -1) {\n if (index > lastVisibleIndex) {\n item = React.cloneElement(childNode, // 这里修改 eventKey 是为了防止隐藏状态下还会触发 openkeys 事件\n {\n style: {\n display: 'none'\n },\n eventKey: \"\".concat(childNode.props.eventKey, \"-hidden\"),\n\n /**\n * Legacy code. Here `className` never used:\n * https://github.com/react-component/menu/commit/4cd6b49fce9d116726f4ea00dda85325d6f26500#diff-e2fa48f75c2dd2318295cde428556a76R240\n */\n className: \"\".concat(MENUITEM_OVERFLOWED_CLASSNAME)\n });\n }\n\n if (index === lastVisibleIndex + 1) {\n _this3.overflowedItems = children.slice(lastVisibleIndex + 1).map(function (c) {\n return React.cloneElement(c, // children[index].key will become '.$key' in clone by default,\n // we have to overwrite with the correct key explicitly\n {\n key: c.props.eventKey,\n mode: 'vertical-left'\n });\n });\n overflowed = _this3.getOverflowedSubMenuItem(childNode.props.eventKey, _this3.overflowedItems);\n }\n }\n\n var ret = [].concat(_toConsumableArray(acc), [overflowed, item]);\n\n if (index === children.length - 1) {\n // need a placeholder for calculating overflowed indicator width\n ret.push(_this3.getOverflowedSubMenuItem(childNode.props.eventKey, [], true));\n }\n\n return ret;\n }\n\n return [].concat(_toConsumableArray(acc), [item]);\n }, []);\n }\n }, {\n key: \"render\",\n value: function render() {\n var _this$props2 = this.props,\n visible = _this$props2.visible,\n prefixCls = _this$props2.prefixCls,\n overflowedIndicator = _this$props2.overflowedIndicator,\n mode = _this$props2.mode,\n level = _this$props2.level,\n tag = _this$props2.tag,\n children = _this$props2.children,\n theme = _this$props2.theme,\n rest = _objectWithoutProperties(_this$props2, [\"visible\", \"prefixCls\", \"overflowedIndicator\", \"mode\", \"level\", \"tag\", \"children\", \"theme\"]);\n\n var Tag = tag;\n return React.createElement(Tag, Object.assign({}, rest), this.renderChildren(children));\n }\n }]);\n\n return DOMWrap;\n}(React.Component);\n\nDOMWrap.defaultProps = {\n tag: 'div',\n className: ''\n};\nexport default DOMWrap;","function _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nimport * as React from 'react';\nimport { connect } from 'mini-store';\nimport KeyCode from \"rc-util/es/KeyCode\";\nimport createChainedFunction from \"rc-util/es/createChainedFunction\";\nimport shallowEqual from 'shallowequal';\nimport classNames from 'classnames';\nimport { getKeyFromChildrenIndex, loopMenuItem, noop, menuAllProps, isMobileDevice } from './util';\nimport DOMWrap from './DOMWrap';\n\nfunction allDisabled(arr) {\n if (!arr.length) {\n return true;\n }\n\n return arr.every(function (c) {\n return !!c.props.disabled;\n });\n}\n\nfunction updateActiveKey(store, menuId, activeKey) {\n var state = store.getState();\n store.setState({\n activeKey: _objectSpread({}, state.activeKey, _defineProperty({}, menuId, activeKey))\n });\n}\n\nfunction getEventKey(props) {\n // when eventKey not available ,it's menu and return menu id '0-menu-'\n return props.eventKey || '0-menu-';\n}\n\nexport function getActiveKey(props, originalActiveKey) {\n var activeKey = originalActiveKey;\n var children = props.children,\n eventKey = props.eventKey;\n\n if (activeKey) {\n var found;\n loopMenuItem(children, function (c, i) {\n if (c && c.props && !c.props.disabled && activeKey === getKeyFromChildrenIndex(c, eventKey, i)) {\n found = true;\n }\n });\n\n if (found) {\n return activeKey;\n }\n }\n\n activeKey = null;\n\n if (props.defaultActiveFirst) {\n loopMenuItem(children, function (c, i) {\n if (!activeKey && c && !c.props.disabled) {\n activeKey = getKeyFromChildrenIndex(c, eventKey, i);\n }\n });\n return activeKey;\n }\n\n return activeKey;\n}\nexport function saveRef(c) {\n if (c) {\n var index = this.instanceArray.indexOf(c);\n\n if (index !== -1) {\n // update component if it's already inside instanceArray\n this.instanceArray[index] = c;\n } else {\n // add component if it's not in instanceArray yet;\n this.instanceArray.push(c);\n }\n }\n}\nexport var SubPopupMenu =\n/*#__PURE__*/\nfunction (_React$Component) {\n _inherits(SubPopupMenu, _React$Component);\n\n function SubPopupMenu(props) {\n var _this;\n\n _classCallCheck(this, SubPopupMenu);\n\n _this = _possibleConstructorReturn(this, _getPrototypeOf(SubPopupMenu).call(this, props));\n /**\n * all keyboard events callbacks run from here at first\n *\n * note:\n * This legacy code that `onKeyDown` is called by parent instead of dom self.\n * which need return code to check if this event is handled\n */\n\n _this.onKeyDown = function (e, callback) {\n var keyCode = e.keyCode;\n var handled;\n\n _this.getFlatInstanceArray().forEach(function (obj) {\n if (obj && obj.props.active && obj.onKeyDown) {\n handled = obj.onKeyDown(e);\n }\n });\n\n if (handled) {\n return 1;\n }\n\n var activeItem = null;\n\n if (keyCode === KeyCode.UP || keyCode === KeyCode.DOWN) {\n activeItem = _this.step(keyCode === KeyCode.UP ? -1 : 1);\n }\n\n if (activeItem) {\n e.preventDefault();\n updateActiveKey(_this.props.store, getEventKey(_this.props), activeItem.props.eventKey);\n\n if (typeof callback === 'function') {\n callback(activeItem);\n }\n\n return 1;\n }\n\n return undefined;\n };\n\n _this.onItemHover = function (e) {\n var key = e.key,\n hover = e.hover;\n updateActiveKey(_this.props.store, getEventKey(_this.props), hover ? key : null);\n };\n\n _this.onDeselect = function (selectInfo) {\n _this.props.onDeselect(selectInfo);\n };\n\n _this.onSelect = function (selectInfo) {\n _this.props.onSelect(selectInfo);\n };\n\n _this.onClick = function (e) {\n _this.props.onClick(e);\n };\n\n _this.onOpenChange = function (e) {\n _this.props.onOpenChange(e);\n };\n\n _this.onDestroy = function (key) {\n /* istanbul ignore next */\n _this.props.onDestroy(key);\n };\n\n _this.getFlatInstanceArray = function () {\n return _this.instanceArray;\n };\n\n _this.step = function (direction) {\n var children = _this.getFlatInstanceArray();\n\n var activeKey = _this.props.store.getState().activeKey[getEventKey(_this.props)];\n\n var len = children.length;\n\n if (!len) {\n return null;\n }\n\n if (direction < 0) {\n children = children.concat().reverse();\n } // find current activeIndex\n\n\n var activeIndex = -1;\n children.every(function (c, ci) {\n if (c && c.props.eventKey === activeKey) {\n activeIndex = ci;\n return false;\n }\n\n return true;\n });\n\n if (!_this.props.defaultActiveFirst && activeIndex !== -1 && allDisabled(children.slice(activeIndex, len - 1))) {\n return undefined;\n }\n\n var start = (activeIndex + 1) % len;\n var i = start;\n\n do {\n var child = children[i];\n\n if (!child || child.props.disabled) {\n i = (i + 1) % len;\n } else {\n return child;\n }\n } while (i !== start);\n\n return null;\n };\n\n _this.renderCommonMenuItem = function (child, i, extraProps) {\n var state = _this.props.store.getState();\n\n var _assertThisInitialize = _assertThisInitialized(_this),\n props = _assertThisInitialize.props;\n\n var key = getKeyFromChildrenIndex(child, props.eventKey, i);\n var childProps = child.props; // https://github.com/ant-design/ant-design/issues/11517#issuecomment-477403055\n\n if (!childProps || typeof child.type === 'string') {\n return child;\n }\n\n var isActive = key === state.activeKey;\n\n var newChildProps = _objectSpread({\n mode: childProps.mode || props.mode,\n level: props.level,\n inlineIndent: props.inlineIndent,\n renderMenuItem: _this.renderMenuItem,\n rootPrefixCls: props.prefixCls,\n index: i,\n parentMenu: props.parentMenu,\n // customized ref function, need to be invoked manually in child's componentDidMount\n manualRef: childProps.disabled ? undefined : createChainedFunction(child.ref, saveRef.bind(_assertThisInitialized(_this))),\n eventKey: key,\n active: !childProps.disabled && isActive,\n multiple: props.multiple,\n onClick: function onClick(e) {\n (childProps.onClick || noop)(e);\n\n _this.onClick(e);\n },\n onItemHover: _this.onItemHover,\n motion: props.motion,\n subMenuOpenDelay: props.subMenuOpenDelay,\n subMenuCloseDelay: props.subMenuCloseDelay,\n forceSubMenuRender: props.forceSubMenuRender,\n onOpenChange: _this.onOpenChange,\n onDeselect: _this.onDeselect,\n onSelect: _this.onSelect,\n builtinPlacements: props.builtinPlacements,\n itemIcon: childProps.itemIcon || _this.props.itemIcon,\n expandIcon: childProps.expandIcon || _this.props.expandIcon\n }, extraProps); // ref: https://github.com/ant-design/ant-design/issues/13943\n\n\n if (props.mode === 'inline' || isMobileDevice()) {\n newChildProps.triggerSubMenuAction = 'click';\n }\n\n return React.cloneElement(child, newChildProps);\n };\n\n _this.renderMenuItem = function (c, i, subMenuKey) {\n /* istanbul ignore if */\n if (!c) {\n return null;\n }\n\n var state = _this.props.store.getState();\n\n var extraProps = {\n openKeys: state.openKeys,\n selectedKeys: state.selectedKeys,\n triggerSubMenuAction: _this.props.triggerSubMenuAction,\n subMenuKey: subMenuKey\n };\n return _this.renderCommonMenuItem(c, i, extraProps);\n };\n\n props.store.setState({\n activeKey: _objectSpread({}, props.store.getState().activeKey, _defineProperty({}, props.eventKey, getActiveKey(props, props.activeKey)))\n });\n _this.instanceArray = [];\n return _this;\n }\n\n _createClass(SubPopupMenu, [{\n key: \"componentDidMount\",\n value: function componentDidMount() {\n // invoke customized ref to expose component to mixin\n if (this.props.manualRef) {\n this.props.manualRef(this);\n }\n }\n }, {\n key: \"shouldComponentUpdate\",\n value: function shouldComponentUpdate(nextProps) {\n return this.props.visible || nextProps.visible || this.props.className !== nextProps.className || !shallowEqual(this.props.style, nextProps.style);\n }\n }, {\n key: \"componentDidUpdate\",\n value: function componentDidUpdate(prevProps) {\n var props = this.props;\n var originalActiveKey = 'activeKey' in props ? props.activeKey : props.store.getState().activeKey[getEventKey(props)];\n var activeKey = getActiveKey(props, originalActiveKey);\n\n if (activeKey !== originalActiveKey) {\n updateActiveKey(props.store, getEventKey(props), activeKey);\n } else if ('activeKey' in prevProps) {\n // If prev activeKey is not same as current activeKey,\n // we should set it.\n var prevActiveKey = getActiveKey(prevProps, prevProps.activeKey);\n\n if (activeKey !== prevActiveKey) {\n updateActiveKey(props.store, getEventKey(props), activeKey);\n }\n }\n }\n }, {\n key: \"render\",\n value: function render() {\n var _this2 = this;\n\n var props = _extends({}, this.props);\n\n this.instanceArray = [];\n var className = classNames(props.prefixCls, props.className, \"\".concat(props.prefixCls, \"-\").concat(props.mode));\n var domProps = {\n className: className,\n // role could be 'select' and by default set to menu\n role: props.role || 'menu'\n };\n\n if (props.id) {\n domProps.id = props.id;\n }\n\n if (props.focusable) {\n domProps.tabIndex = 0;\n domProps.onKeyDown = this.onKeyDown;\n }\n\n var prefixCls = props.prefixCls,\n eventKey = props.eventKey,\n visible = props.visible,\n level = props.level,\n mode = props.mode,\n overflowedIndicator = props.overflowedIndicator,\n theme = props.theme;\n menuAllProps.forEach(function (key) {\n return delete props[key];\n }); // Otherwise, the propagated click event will trigger another onClick\n\n delete props.onClick;\n return React.createElement(DOMWrap, Object.assign({}, props, {\n prefixCls: prefixCls,\n mode: mode,\n tag: \"ul\",\n level: level,\n theme: theme,\n visible: visible,\n overflowedIndicator: overflowedIndicator\n }, domProps), React.Children.map(props.children, function (c, i) {\n return _this2.renderMenuItem(c, i, eventKey || '0-menu-');\n }));\n }\n }]);\n\n return SubPopupMenu;\n}(React.Component);\nSubPopupMenu.defaultProps = {\n prefixCls: 'rc-menu',\n className: '',\n mode: 'vertical',\n level: 1,\n inlineIndent: 24,\n visible: true,\n focusable: true,\n style: {},\n manualRef: noop\n};\nvar connected = connect()(SubPopupMenu);\nexport default connected;","/* eslint-disable no-console */\nvar warned = {};\nexport function warning(valid, message) {\n // Support uglify\n if (process.env.NODE_ENV !== 'production' && !valid && console !== undefined) {\n console.error(\"Warning: \".concat(message));\n }\n}\nexport function note(valid, message) {\n // Support uglify\n if (process.env.NODE_ENV !== 'production' && !valid && console !== undefined) {\n console.warn(\"Note: \".concat(message));\n }\n}\nexport function resetWarned() {\n warned = {};\n}\nexport function call(method, valid, message) {\n if (!valid && !warned[message]) {\n method(false, message);\n warned[message] = true;\n }\n}\nexport function warningOnce(valid, message) {\n call(warning, valid, message);\n}\nexport function noteOnce(valid, message) {\n call(note, valid, message);\n}\nexport default warningOnce;\n/* eslint-enable */","function _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nimport warning from \"rc-util/es/warning\";\nexport function getMotion(_ref) {\n var prefixCls = _ref.prefixCls,\n motion = _ref.motion,\n openAnimation = _ref.openAnimation,\n openTransitionName = _ref.openTransitionName;\n\n if (motion) {\n return motion;\n }\n\n if (_typeof(openAnimation) === 'object' && openAnimation) {\n warning(false, 'Object type of `openAnimation` is removed. Please use `motion` instead.');\n } else if (typeof openAnimation === 'string') {\n return {\n motionName: \"\".concat(prefixCls, \"-open-\").concat(openAnimation)\n };\n }\n\n if (openTransitionName) {\n return {\n motionName: openTransitionName\n };\n }\n\n return null;\n}","function _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nimport * as React from 'react';\nimport { Provider, create } from 'mini-store';\nimport SubPopupMenu, { getActiveKey } from './SubPopupMenu';\nimport { noop } from './util';\nimport { getMotion } from './utils/legacyUtil';\n\nvar Menu =\n/*#__PURE__*/\nfunction (_React$Component) {\n _inherits(Menu, _React$Component);\n\n function Menu(props) {\n var _this;\n\n _classCallCheck(this, Menu);\n\n _this = _possibleConstructorReturn(this, _getPrototypeOf(Menu).call(this, props));\n\n _this.onSelect = function (selectInfo) {\n var _assertThisInitialize = _assertThisInitialized(_this),\n props = _assertThisInitialize.props;\n\n if (props.selectable) {\n // root menu\n var _this$store$getState = _this.store.getState(),\n _selectedKeys = _this$store$getState.selectedKeys;\n\n var selectedKey = selectInfo.key;\n\n if (props.multiple) {\n _selectedKeys = _selectedKeys.concat([selectedKey]);\n } else {\n _selectedKeys = [selectedKey];\n }\n\n if (!('selectedKeys' in props)) {\n _this.store.setState({\n selectedKeys: _selectedKeys\n });\n }\n\n props.onSelect(_objectSpread({}, selectInfo, {\n selectedKeys: _selectedKeys\n }));\n }\n };\n\n _this.onClick = function (e) {\n _this.props.onClick(e);\n }; // onKeyDown needs to be exposed as a instance method\n // e.g., in rc-select, we need to navigate menu item while\n // current active item is rc-select input box rather than the menu itself\n\n\n _this.onKeyDown = function (e, callback) {\n _this.innerMenu.getWrappedInstance().onKeyDown(e, callback);\n };\n\n _this.onOpenChange = function (event) {\n var _assertThisInitialize2 = _assertThisInitialized(_this),\n props = _assertThisInitialize2.props;\n\n var openKeys = _this.store.getState().openKeys.concat();\n\n var changed = false;\n\n var processSingle = function processSingle(e) {\n var oneChanged = false;\n\n if (e.open) {\n oneChanged = openKeys.indexOf(e.key) === -1;\n\n if (oneChanged) {\n openKeys.push(e.key);\n }\n } else {\n var index = openKeys.indexOf(e.key);\n oneChanged = index !== -1;\n\n if (oneChanged) {\n openKeys.splice(index, 1);\n }\n }\n\n changed = changed || oneChanged;\n };\n\n if (Array.isArray(event)) {\n // batch change call\n event.forEach(processSingle);\n } else {\n processSingle(event);\n }\n\n if (changed) {\n if (!('openKeys' in _this.props)) {\n _this.store.setState({\n openKeys: openKeys\n });\n }\n\n props.onOpenChange(openKeys);\n }\n };\n\n _this.onDeselect = function (selectInfo) {\n var _assertThisInitialize3 = _assertThisInitialized(_this),\n props = _assertThisInitialize3.props;\n\n if (props.selectable) {\n var _selectedKeys2 = _this.store.getState().selectedKeys.concat();\n\n var selectedKey = selectInfo.key;\n\n var index = _selectedKeys2.indexOf(selectedKey);\n\n if (index !== -1) {\n _selectedKeys2.splice(index, 1);\n }\n\n if (!('selectedKeys' in props)) {\n _this.store.setState({\n selectedKeys: _selectedKeys2\n });\n }\n\n props.onDeselect(_objectSpread({}, selectInfo, {\n selectedKeys: _selectedKeys2\n }));\n }\n };\n\n _this.getOpenTransitionName = function () {\n var _assertThisInitialize4 = _assertThisInitialized(_this),\n props = _assertThisInitialize4.props;\n\n var transitionName = props.openTransitionName;\n var animationName = props.openAnimation;\n\n if (!transitionName && typeof animationName === 'string') {\n transitionName = \"\".concat(props.prefixCls, \"-open-\").concat(animationName);\n }\n\n return transitionName;\n };\n\n _this.setInnerMenu = function (node) {\n _this.innerMenu = node;\n };\n\n _this.isRootMenu = true;\n var selectedKeys = props.defaultSelectedKeys;\n var openKeys = props.defaultOpenKeys;\n\n if ('selectedKeys' in props) {\n selectedKeys = props.selectedKeys || [];\n }\n\n if ('openKeys' in props) {\n openKeys = props.openKeys || [];\n }\n\n _this.store = create({\n selectedKeys: selectedKeys,\n openKeys: openKeys,\n activeKey: {\n '0-menu-': getActiveKey(props, props.activeKey)\n }\n });\n return _this;\n }\n\n _createClass(Menu, [{\n key: \"componentDidMount\",\n value: function componentDidMount() {\n this.updateMiniStore();\n }\n }, {\n key: \"componentDidUpdate\",\n value: function componentDidUpdate() {\n this.updateMiniStore();\n }\n }, {\n key: \"updateMiniStore\",\n value: function updateMiniStore() {\n if ('selectedKeys' in this.props) {\n this.store.setState({\n selectedKeys: this.props.selectedKeys || []\n });\n }\n\n if ('openKeys' in this.props) {\n this.store.setState({\n openKeys: this.props.openKeys || []\n });\n }\n }\n }, {\n key: \"render\",\n value: function render() {\n var props = _objectSpread({}, this.props);\n\n props.className += \" \".concat(props.prefixCls, \"-root\");\n props = _objectSpread({}, props, {\n onClick: this.onClick,\n onOpenChange: this.onOpenChange,\n onDeselect: this.onDeselect,\n onSelect: this.onSelect,\n parentMenu: this,\n motion: getMotion(this.props)\n });\n delete props.openAnimation;\n delete props.openTransitionName;\n return React.createElement(Provider, {\n store: this.store\n }, React.createElement(SubPopupMenu, Object.assign({}, props, {\n ref: this.setInnerMenu\n }), this.props.children));\n }\n }]);\n\n return Menu;\n}(React.Component);\n\nMenu.defaultProps = {\n selectable: true,\n onClick: noop,\n onSelect: noop,\n onOpenChange: noop,\n onDeselect: noop,\n defaultSelectedKeys: [],\n defaultOpenKeys: [],\n subMenuOpenDelay: 0.1,\n subMenuCloseDelay: 0.1,\n triggerSubMenuAction: 'hover',\n prefixCls: 'rc-menu',\n className: '',\n mode: 'vertical',\n style: {},\n builtinPlacements: {},\n overflowedIndicator: React.createElement(\"span\", null, \"\\xB7\\xB7\\xB7\")\n};\nexport default Menu;","function _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nimport * as React from 'react';\nimport * as ReactDOM from 'react-dom';\nimport KeyCode from \"rc-util/es/KeyCode\";\nimport classNames from 'classnames';\nimport scrollIntoView from 'dom-scroll-into-view';\nimport { connect } from 'mini-store';\nimport { noop, menuAllProps } from './util';\nexport var MenuItem =\n/*#__PURE__*/\nfunction (_React$Component) {\n _inherits(MenuItem, _React$Component);\n\n function MenuItem() {\n var _this;\n\n _classCallCheck(this, MenuItem);\n\n _this = _possibleConstructorReturn(this, _getPrototypeOf(MenuItem).apply(this, arguments));\n\n _this.onKeyDown = function (e) {\n var keyCode = e.keyCode;\n\n if (keyCode === KeyCode.ENTER) {\n _this.onClick(e);\n\n return true;\n }\n\n return undefined;\n };\n\n _this.onMouseLeave = function (e) {\n var _this$props = _this.props,\n eventKey = _this$props.eventKey,\n onItemHover = _this$props.onItemHover,\n onMouseLeave = _this$props.onMouseLeave;\n onItemHover({\n key: eventKey,\n hover: false\n });\n onMouseLeave({\n key: eventKey,\n domEvent: e\n });\n };\n\n _this.onMouseEnter = function (e) {\n var _this$props2 = _this.props,\n eventKey = _this$props2.eventKey,\n onItemHover = _this$props2.onItemHover,\n onMouseEnter = _this$props2.onMouseEnter;\n onItemHover({\n key: eventKey,\n hover: true\n });\n onMouseEnter({\n key: eventKey,\n domEvent: e\n });\n };\n\n _this.onClick = function (e) {\n var _this$props3 = _this.props,\n eventKey = _this$props3.eventKey,\n multiple = _this$props3.multiple,\n onClick = _this$props3.onClick,\n onSelect = _this$props3.onSelect,\n onDeselect = _this$props3.onDeselect,\n isSelected = _this$props3.isSelected;\n var info = {\n key: eventKey,\n keyPath: [eventKey],\n item: _assertThisInitialized(_this),\n domEvent: e\n };\n onClick(info);\n\n if (multiple) {\n if (isSelected) {\n onDeselect(info);\n } else {\n onSelect(info);\n }\n } else if (!isSelected) {\n onSelect(info);\n }\n };\n\n _this.saveNode = function (node) {\n _this.node = node;\n };\n\n return _this;\n }\n\n _createClass(MenuItem, [{\n key: \"componentDidMount\",\n value: function componentDidMount() {\n // invoke customized ref to expose component to mixin\n this.callRef();\n }\n }, {\n key: \"componentDidUpdate\",\n value: function componentDidUpdate(prevProps) {\n var _this$props4 = this.props,\n active = _this$props4.active,\n parentMenu = _this$props4.parentMenu,\n eventKey = _this$props4.eventKey; // 在 parentMenu 上层保存滚动状态,避免重复的 MenuItem key 导致滚动跳动\n // https://github.com/ant-design/ant-design/issues/16181\n\n if (!prevProps.active && active && (!parentMenu || !parentMenu[\"scrolled-\".concat(eventKey)])) {\n if (this.node) {\n scrollIntoView(this.node, ReactDOM.findDOMNode(parentMenu), {\n onlyScrollIfNeeded: true\n });\n parentMenu[\"scrolled-\".concat(eventKey)] = true;\n }\n } else if (parentMenu && parentMenu[\"scrolled-\".concat(eventKey)]) {\n delete parentMenu[\"scrolled-\".concat(eventKey)];\n }\n\n this.callRef();\n }\n }, {\n key: \"componentWillUnmount\",\n value: function componentWillUnmount() {\n var props = this.props;\n\n if (props.onDestroy) {\n props.onDestroy(props.eventKey);\n }\n }\n }, {\n key: \"getPrefixCls\",\n value: function getPrefixCls() {\n return \"\".concat(this.props.rootPrefixCls, \"-item\");\n }\n }, {\n key: \"getActiveClassName\",\n value: function getActiveClassName() {\n return \"\".concat(this.getPrefixCls(), \"-active\");\n }\n }, {\n key: \"getSelectedClassName\",\n value: function getSelectedClassName() {\n return \"\".concat(this.getPrefixCls(), \"-selected\");\n }\n }, {\n key: \"getDisabledClassName\",\n value: function getDisabledClassName() {\n return \"\".concat(this.getPrefixCls(), \"-disabled\");\n }\n }, {\n key: \"callRef\",\n value: function callRef() {\n if (this.props.manualRef) {\n this.props.manualRef(this);\n }\n }\n }, {\n key: \"render\",\n value: function render() {\n var _classNames;\n\n var props = _objectSpread({}, this.props);\n\n var className = classNames(this.getPrefixCls(), props.className, (_classNames = {}, _defineProperty(_classNames, this.getActiveClassName(), !props.disabled && props.active), _defineProperty(_classNames, this.getSelectedClassName(), props.isSelected), _defineProperty(_classNames, this.getDisabledClassName(), props.disabled), _classNames));\n\n var attrs = _objectSpread({}, props.attribute, {\n title: props.title,\n className: className,\n // set to menuitem by default\n role: props.role || 'menuitem',\n 'aria-disabled': props.disabled\n });\n\n if (props.role === 'option') {\n // overwrite to option\n attrs = _objectSpread({}, attrs, {\n role: 'option',\n 'aria-selected': props.isSelected\n });\n } else if (props.role === null || props.role === 'none') {\n // sometimes we want to specify role inside element\n //
would be a good example\n // in this case the role on should be \"none\" to\n // remove the implied listitem role.\n // https://www.w3.org/TR/wai-aria-practices-1.1/examples/menubar/menubar-1/menubar-1.html\n attrs.role = 'none';\n } // In case that onClick/onMouseLeave/onMouseEnter is passed down from owner\n\n\n var mouseEvent = {\n onClick: props.disabled ? null : this.onClick,\n onMouseLeave: props.disabled ? null : this.onMouseLeave,\n onMouseEnter: props.disabled ? null : this.onMouseEnter\n };\n\n var style = _objectSpread({}, props.style);\n\n if (props.mode === 'inline') {\n style.paddingLeft = props.inlineIndent * props.level;\n }\n\n menuAllProps.forEach(function (key) {\n return delete props[key];\n });\n var icon = this.props.itemIcon;\n\n if (typeof this.props.itemIcon === 'function') {\n // TODO: This is a bug which should fixed after TS refactor\n icon = React.createElement(this.props.itemIcon, this.props);\n }\n\n return React.createElement(\"li\", Object.assign({}, props, attrs, mouseEvent, {\n style: style,\n ref: this.saveNode\n }), props.children, icon);\n }\n }]);\n\n return MenuItem;\n}(React.Component);\nMenuItem.isMenuItem = true;\nMenuItem.defaultProps = {\n onSelect: noop,\n onMouseEnter: noop,\n onMouseLeave: noop,\n manualRef: noop\n};\nvar connected = connect(function (_ref, _ref2) {\n var activeKey = _ref.activeKey,\n selectedKeys = _ref.selectedKeys;\n var eventKey = _ref2.eventKey,\n subMenuKey = _ref2.subMenuKey;\n return {\n active: activeKey[subMenuKey] === eventKey,\n isSelected: selectedKeys.indexOf(eventKey) !== -1\n };\n})(MenuItem);\nexport default connected;","function _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nimport * as React from 'react';\nimport { menuAllProps } from './util';\n\nvar MenuItemGroup =\n/*#__PURE__*/\nfunction (_React$Component) {\n _inherits(MenuItemGroup, _React$Component);\n\n function MenuItemGroup() {\n var _this;\n\n _classCallCheck(this, MenuItemGroup);\n\n _this = _possibleConstructorReturn(this, _getPrototypeOf(MenuItemGroup).apply(this, arguments));\n\n _this.renderInnerMenuItem = function (item) {\n var _this$props = _this.props,\n renderMenuItem = _this$props.renderMenuItem,\n index = _this$props.index;\n return renderMenuItem(item, index, _this.props.subMenuKey);\n };\n\n return _this;\n }\n\n _createClass(MenuItemGroup, [{\n key: \"render\",\n value: function render() {\n var props = _extends({}, this.props);\n\n var _props$className = props.className,\n className = _props$className === void 0 ? '' : _props$className,\n rootPrefixCls = props.rootPrefixCls;\n var titleClassName = \"\".concat(rootPrefixCls, \"-item-group-title\");\n var listClassName = \"\".concat(rootPrefixCls, \"-item-group-list\");\n var title = props.title,\n children = props.children;\n menuAllProps.forEach(function (key) {\n return delete props[key];\n }); // Set onClick to null, to ignore propagated onClick event\n\n delete props.onClick;\n return React.createElement(\"li\", Object.assign({}, props, {\n className: \"\".concat(className, \" \").concat(rootPrefixCls, \"-item-group\")\n }), React.createElement(\"div\", {\n className: titleClassName,\n title: typeof title === 'string' ? title : undefined\n }, title), React.createElement(\"ul\", {\n className: listClassName\n }, React.Children.map(children, this.renderInnerMenuItem)));\n }\n }]);\n\n return MenuItemGroup;\n}(React.Component);\n\nMenuItemGroup.isMenuItemGroup = true;\nMenuItemGroup.defaultProps = {\n disabled: true\n};\nexport default MenuItemGroup;","import * as React from 'react';\n\nvar Divider = function Divider(_ref) {\n var className = _ref.className,\n rootPrefixCls = _ref.rootPrefixCls,\n style = _ref.style;\n return React.createElement(\"li\", {\n className: \"\".concat(className, \" \").concat(rootPrefixCls, \"-item-divider\"),\n style: style\n });\n};\n\nDivider.defaultProps = {\n // To fix keyboard UX.\n disabled: true,\n className: '',\n style: {}\n};\nexport default Divider;","import Menu from './Menu';\nimport SubMenu from './SubMenu';\nimport MenuItem from './MenuItem';\nimport MenuItemGroup from './MenuItemGroup';\nimport Divider from './Divider';\nexport { SubMenu, MenuItem as Item, MenuItem, MenuItemGroup, MenuItemGroup as ItemGroup, Divider };\nexport default Menu;","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 _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 _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 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","/*\r\n * @namespace Util\r\n *\r\n * Various utility functions, used by Leaflet internally.\r\n */\r\n\r\nexport var freeze = Object.freeze;\r\nObject.freeze = function (obj) { return obj; };\r\n\r\n// @function extend(dest: Object, src?: Object): Object\r\n// Merges the properties of the `src` object (or multiple objects) into `dest` object and returns the latter. Has an `L.extend` shortcut.\r\nexport function extend(dest) {\r\n\tvar i, j, len, src;\r\n\r\n\tfor (j = 1, len = arguments.length; j < len; j++) {\r\n\t\tsrc = arguments[j];\r\n\t\tfor (i in src) {\r\n\t\t\tdest[i] = src[i];\r\n\t\t}\r\n\t}\r\n\treturn dest;\r\n}\r\n\r\n// @function create(proto: Object, properties?: Object): Object\r\n// Compatibility polyfill for [Object.create](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/create)\r\nexport var create = Object.create || (function () {\r\n\tfunction F() {}\r\n\treturn function (proto) {\r\n\t\tF.prototype = proto;\r\n\t\treturn new F();\r\n\t};\r\n})();\r\n\r\n// @function bind(fn: Function, …): Function\r\n// Returns a new function bound to the arguments passed, like [Function.prototype.bind](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Function/bind).\r\n// Has a `L.bind()` shortcut.\r\nexport function bind(fn, obj) {\r\n\tvar slice = Array.prototype.slice;\r\n\r\n\tif (fn.bind) {\r\n\t\treturn fn.bind.apply(fn, slice.call(arguments, 1));\r\n\t}\r\n\r\n\tvar args = slice.call(arguments, 2);\r\n\r\n\treturn function () {\r\n\t\treturn fn.apply(obj, args.length ? args.concat(slice.call(arguments)) : arguments);\r\n\t};\r\n}\r\n\r\n// @property lastId: Number\r\n// Last unique ID used by [`stamp()`](#util-stamp)\r\nexport var lastId = 0;\r\n\r\n// @function stamp(obj: Object): Number\r\n// Returns the unique ID of an object, assigning it one if it doesn't have it.\r\nexport function stamp(obj) {\r\n\t/*eslint-disable */\r\n\tobj._leaflet_id = obj._leaflet_id || ++lastId;\r\n\treturn obj._leaflet_id;\r\n\t/* eslint-enable */\r\n}\r\n\r\n// @function throttle(fn: Function, time: Number, context: Object): Function\r\n// Returns a function which executes function `fn` with the given scope `context`\r\n// (so that the `this` keyword refers to `context` inside `fn`'s code). The function\r\n// `fn` will be called no more than one time per given amount of `time`. The arguments\r\n// received by the bound function will be any arguments passed when binding the\r\n// function, followed by any arguments passed when invoking the bound function.\r\n// Has an `L.throttle` shortcut.\r\nexport function throttle(fn, time, context) {\r\n\tvar lock, args, wrapperFn, later;\r\n\r\n\tlater = function () {\r\n\t\t// reset lock and call if queued\r\n\t\tlock = false;\r\n\t\tif (args) {\r\n\t\t\twrapperFn.apply(context, args);\r\n\t\t\targs = false;\r\n\t\t}\r\n\t};\r\n\r\n\twrapperFn = function () {\r\n\t\tif (lock) {\r\n\t\t\t// called too soon, queue to call later\r\n\t\t\targs = arguments;\r\n\r\n\t\t} else {\r\n\t\t\t// call and lock until later\r\n\t\t\tfn.apply(context, arguments);\r\n\t\t\tsetTimeout(later, time);\r\n\t\t\tlock = true;\r\n\t\t}\r\n\t};\r\n\r\n\treturn wrapperFn;\r\n}\r\n\r\n// @function wrapNum(num: Number, range: Number[], includeMax?: Boolean): Number\r\n// Returns the number `num` modulo `range` in such a way so it lies within\r\n// `range[0]` and `range[1]`. The returned value will be always smaller than\r\n// `range[1]` unless `includeMax` is set to `true`.\r\nexport function wrapNum(x, range, includeMax) {\r\n\tvar max = range[1],\r\n\t min = range[0],\r\n\t d = max - min;\r\n\treturn x === max && includeMax ? x : ((x - min) % d + d) % d + min;\r\n}\r\n\r\n// @function falseFn(): Function\r\n// Returns a function which always returns `false`.\r\nexport function falseFn() { return false; }\r\n\r\n// @function formatNum(num: Number, digits?: Number): Number\r\n// Returns the number `num` rounded to `digits` decimals, or to 6 decimals by default.\r\nexport function formatNum(num, digits) {\r\n\tvar pow = Math.pow(10, (digits === undefined ? 6 : digits));\r\n\treturn Math.round(num * pow) / pow;\r\n}\r\n\r\n// @function trim(str: String): String\r\n// Compatibility polyfill for [String.prototype.trim](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String/Trim)\r\nexport function trim(str) {\r\n\treturn str.trim ? str.trim() : str.replace(/^\\s+|\\s+$/g, '');\r\n}\r\n\r\n// @function splitWords(str: String): String[]\r\n// Trims and splits the string on whitespace and returns the array of parts.\r\nexport function splitWords(str) {\r\n\treturn trim(str).split(/\\s+/);\r\n}\r\n\r\n// @function setOptions(obj: Object, options: Object): Object\r\n// Merges the given properties to the `options` of the `obj` object, returning the resulting options. See `Class options`. Has an `L.setOptions` shortcut.\r\nexport function setOptions(obj, options) {\r\n\tif (!obj.hasOwnProperty('options')) {\r\n\t\tobj.options = obj.options ? create(obj.options) : {};\r\n\t}\r\n\tfor (var i in options) {\r\n\t\tobj.options[i] = options[i];\r\n\t}\r\n\treturn obj.options;\r\n}\r\n\r\n// @function getParamString(obj: Object, existingUrl?: String, uppercase?: Boolean): String\r\n// Converts an object into a parameter URL string, e.g. `{a: \"foo\", b: \"bar\"}`\r\n// translates to `'?a=foo&b=bar'`. If `existingUrl` is set, the parameters will\r\n// be appended at the end. If `uppercase` is `true`, the parameter names will\r\n// be uppercased (e.g. `'?A=foo&B=bar'`)\r\nexport function getParamString(obj, existingUrl, uppercase) {\r\n\tvar params = [];\r\n\tfor (var i in obj) {\r\n\t\tparams.push(encodeURIComponent(uppercase ? i.toUpperCase() : i) + '=' + encodeURIComponent(obj[i]));\r\n\t}\r\n\treturn ((!existingUrl || existingUrl.indexOf('?') === -1) ? '?' : '&') + params.join('&');\r\n}\r\n\r\nvar templateRe = /\\{ *([\\w_-]+) *\\}/g;\r\n\r\n// @function template(str: String, data: Object): String\r\n// Simple templating facility, accepts a template string of the form `'Hello {a}, {b}'`\r\n// and a data object like `{a: 'foo', b: 'bar'}`, returns evaluated string\r\n// `('Hello foo, bar')`. You can also specify functions instead of strings for\r\n// data values — they will be evaluated passing `data` as an argument.\r\nexport function template(str, data) {\r\n\treturn str.replace(templateRe, function (str, key) {\r\n\t\tvar value = data[key];\r\n\r\n\t\tif (value === undefined) {\r\n\t\t\tthrow new Error('No value provided for variable ' + str);\r\n\r\n\t\t} else if (typeof value === 'function') {\r\n\t\t\tvalue = value(data);\r\n\t\t}\r\n\t\treturn value;\r\n\t});\r\n}\r\n\r\n// @function isArray(obj): Boolean\r\n// Compatibility polyfill for [Array.isArray](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray)\r\nexport var isArray = Array.isArray || function (obj) {\r\n\treturn (Object.prototype.toString.call(obj) === '[object Array]');\r\n};\r\n\r\n// @function indexOf(array: Array, el: Object): Number\r\n// Compatibility polyfill for [Array.prototype.indexOf](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf)\r\nexport function indexOf(array, el) {\r\n\tfor (var i = 0; i < array.length; i++) {\r\n\t\tif (array[i] === el) { return i; }\r\n\t}\r\n\treturn -1;\r\n}\r\n\r\n// @property emptyImageUrl: String\r\n// Data URI string containing a base64-encoded empty GIF image.\r\n// Used as a hack to free memory from unused images on WebKit-powered\r\n// mobile devices (by setting image `src` to this string).\r\nexport var emptyImageUrl = 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=';\r\n\r\n// inspired by http://paulirish.com/2011/requestanimationframe-for-smart-animating/\r\n\r\nfunction getPrefixed(name) {\r\n\treturn window['webkit' + name] || window['moz' + name] || window['ms' + name];\r\n}\r\n\r\nvar lastTime = 0;\r\n\r\n// fallback for IE 7-8\r\nfunction timeoutDefer(fn) {\r\n\tvar time = +new Date(),\r\n\t timeToCall = Math.max(0, 16 - (time - lastTime));\r\n\r\n\tlastTime = time + timeToCall;\r\n\treturn window.setTimeout(fn, timeToCall);\r\n}\r\n\r\nexport var requestFn = window.requestAnimationFrame || getPrefixed('RequestAnimationFrame') || timeoutDefer;\r\nexport var cancelFn = window.cancelAnimationFrame || getPrefixed('CancelAnimationFrame') ||\r\n\t\tgetPrefixed('CancelRequestAnimationFrame') || function (id) { window.clearTimeout(id); };\r\n\r\n// @function requestAnimFrame(fn: Function, context?: Object, immediate?: Boolean): Number\r\n// Schedules `fn` to be executed when the browser repaints. `fn` is bound to\r\n// `context` if given. When `immediate` is set, `fn` is called immediately if\r\n// the browser doesn't have native support for\r\n// [`window.requestAnimationFrame`](https://developer.mozilla.org/docs/Web/API/window/requestAnimationFrame),\r\n// otherwise it's delayed. Returns a request ID that can be used to cancel the request.\r\nexport function requestAnimFrame(fn, context, immediate) {\r\n\tif (immediate && requestFn === timeoutDefer) {\r\n\t\tfn.call(context);\r\n\t} else {\r\n\t\treturn requestFn.call(window, bind(fn, context));\r\n\t}\r\n}\r\n\r\n// @function cancelAnimFrame(id: Number): undefined\r\n// Cancels a previous `requestAnimFrame`. See also [window.cancelAnimationFrame](https://developer.mozilla.org/docs/Web/API/window/cancelAnimationFrame).\r\nexport function cancelAnimFrame(id) {\r\n\tif (id) {\r\n\t\tcancelFn.call(window, id);\r\n\t}\r\n}\r\n","import * as Util from './Util';\r\n\r\n// @class Class\r\n// @aka L.Class\r\n\r\n// @section\r\n// @uninheritable\r\n\r\n// Thanks to John Resig and Dean Edwards for inspiration!\r\n\r\nexport function Class() {}\r\n\r\nClass.extend = function (props) {\r\n\r\n\t// @function extend(props: Object): Function\r\n\t// [Extends the current class](#class-inheritance) given the properties to be included.\r\n\t// Returns a Javascript function that is a class constructor (to be called with `new`).\r\n\tvar NewClass = function () {\r\n\r\n\t\t// call the constructor\r\n\t\tif (this.initialize) {\r\n\t\t\tthis.initialize.apply(this, arguments);\r\n\t\t}\r\n\r\n\t\t// call all constructor hooks\r\n\t\tthis.callInitHooks();\r\n\t};\r\n\r\n\tvar parentProto = NewClass.__super__ = this.prototype;\r\n\r\n\tvar proto = Util.create(parentProto);\r\n\tproto.constructor = NewClass;\r\n\r\n\tNewClass.prototype = proto;\r\n\r\n\t// inherit parent's statics\r\n\tfor (var i in this) {\r\n\t\tif (this.hasOwnProperty(i) && i !== 'prototype' && i !== '__super__') {\r\n\t\t\tNewClass[i] = this[i];\r\n\t\t}\r\n\t}\r\n\r\n\t// mix static properties into the class\r\n\tif (props.statics) {\r\n\t\tUtil.extend(NewClass, props.statics);\r\n\t\tdelete props.statics;\r\n\t}\r\n\r\n\t// mix includes into the prototype\r\n\tif (props.includes) {\r\n\t\tcheckDeprecatedMixinEvents(props.includes);\r\n\t\tUtil.extend.apply(null, [proto].concat(props.includes));\r\n\t\tdelete props.includes;\r\n\t}\r\n\r\n\t// merge options\r\n\tif (proto.options) {\r\n\t\tprops.options = Util.extend(Util.create(proto.options), props.options);\r\n\t}\r\n\r\n\t// mix given properties into the prototype\r\n\tUtil.extend(proto, props);\r\n\r\n\tproto._initHooks = [];\r\n\r\n\t// add method for calling all hooks\r\n\tproto.callInitHooks = function () {\r\n\r\n\t\tif (this._initHooksCalled) { return; }\r\n\r\n\t\tif (parentProto.callInitHooks) {\r\n\t\t\tparentProto.callInitHooks.call(this);\r\n\t\t}\r\n\r\n\t\tthis._initHooksCalled = true;\r\n\r\n\t\tfor (var i = 0, len = proto._initHooks.length; i < len; i++) {\r\n\t\t\tproto._initHooks[i].call(this);\r\n\t\t}\r\n\t};\r\n\r\n\treturn NewClass;\r\n};\r\n\r\n\r\n// @function include(properties: Object): this\r\n// [Includes a mixin](#class-includes) into the current class.\r\nClass.include = function (props) {\r\n\tUtil.extend(this.prototype, props);\r\n\treturn this;\r\n};\r\n\r\n// @function mergeOptions(options: Object): this\r\n// [Merges `options`](#class-options) into the defaults of the class.\r\nClass.mergeOptions = function (options) {\r\n\tUtil.extend(this.prototype.options, options);\r\n\treturn this;\r\n};\r\n\r\n// @function addInitHook(fn: Function): this\r\n// Adds a [constructor hook](#class-constructor-hooks) to the class.\r\nClass.addInitHook = function (fn) { // (Function) || (String, args...)\r\n\tvar args = Array.prototype.slice.call(arguments, 1);\r\n\r\n\tvar init = typeof fn === 'function' ? fn : function () {\r\n\t\tthis[fn].apply(this, args);\r\n\t};\r\n\r\n\tthis.prototype._initHooks = this.prototype._initHooks || [];\r\n\tthis.prototype._initHooks.push(init);\r\n\treturn this;\r\n};\r\n\r\nfunction checkDeprecatedMixinEvents(includes) {\r\n\tif (typeof L === 'undefined' || !L || !L.Mixin) { return; }\r\n\r\n\tincludes = Util.isArray(includes) ? includes : [includes];\r\n\r\n\tfor (var i = 0; i < includes.length; i++) {\r\n\t\tif (includes[i] === L.Mixin.Events) {\r\n\t\t\tconsole.warn('Deprecated include of L.Mixin.Events: ' +\r\n\t\t\t\t'this property will be removed in future releases, ' +\r\n\t\t\t\t'please inherit from L.Evented instead.', new Error().stack);\r\n\t\t}\r\n\t}\r\n}\r\n","import {Class} from './Class';\r\nimport * as Util from './Util';\r\n\r\n/*\r\n * @class Evented\r\n * @aka L.Evented\r\n * @inherits Class\r\n *\r\n * A set of methods shared between event-powered classes (like `Map` and `Marker`). Generally, events allow you to execute some function when something happens with an object (e.g. the user clicks on the map, causing the map to fire `'click'` event).\r\n *\r\n * @example\r\n *\r\n * ```js\r\n * map.on('click', function(e) {\r\n * \talert(e.latlng);\r\n * } );\r\n * ```\r\n *\r\n * Leaflet deals with event listeners by reference, so if you want to add a listener and then remove it, define it as a function:\r\n *\r\n * ```js\r\n * function onClick(e) { ... }\r\n *\r\n * map.on('click', onClick);\r\n * map.off('click', onClick);\r\n * ```\r\n */\r\n\r\nexport var Events = {\r\n\t/* @method on(type: String, fn: Function, context?: Object): this\r\n\t * Adds a listener function (`fn`) to a particular event type of the object. You can optionally specify the context of the listener (object the this keyword will point to). You can also pass several space-separated types (e.g. `'click dblclick'`).\r\n\t *\r\n\t * @alternative\r\n\t * @method on(eventMap: Object): this\r\n\t * Adds a set of type/listener pairs, e.g. `{click: onClick, mousemove: onMouseMove}`\r\n\t */\r\n\ton: function (types, fn, context) {\r\n\r\n\t\t// types can be a map of types/handlers\r\n\t\tif (typeof types === 'object') {\r\n\t\t\tfor (var type in types) {\r\n\t\t\t\t// we don't process space-separated events here for performance;\r\n\t\t\t\t// it's a hot path since Layer uses the on(obj) syntax\r\n\t\t\t\tthis._on(type, types[type], fn);\r\n\t\t\t}\r\n\r\n\t\t} else {\r\n\t\t\t// types can be a string of space-separated words\r\n\t\t\ttypes = Util.splitWords(types);\r\n\r\n\t\t\tfor (var i = 0, len = types.length; i < len; i++) {\r\n\t\t\t\tthis._on(types[i], fn, context);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn this;\r\n\t},\r\n\r\n\t/* @method off(type: String, fn?: Function, context?: Object): this\r\n\t * Removes a previously added listener function. If no function is specified, it will remove all the listeners of that particular event from the object. Note that if you passed a custom context to `on`, you must pass the same context to `off` in order to remove the listener.\r\n\t *\r\n\t * @alternative\r\n\t * @method off(eventMap: Object): this\r\n\t * Removes a set of type/listener pairs.\r\n\t *\r\n\t * @alternative\r\n\t * @method off: this\r\n\t * Removes all listeners to all events on the object. This includes implicitly attached events.\r\n\t */\r\n\toff: function (types, fn, context) {\r\n\r\n\t\tif (!types) {\r\n\t\t\t// clear all listeners if called without arguments\r\n\t\t\tdelete this._events;\r\n\r\n\t\t} else if (typeof types === 'object') {\r\n\t\t\tfor (var type in types) {\r\n\t\t\t\tthis._off(type, types[type], fn);\r\n\t\t\t}\r\n\r\n\t\t} else {\r\n\t\t\ttypes = Util.splitWords(types);\r\n\r\n\t\t\tfor (var i = 0, len = types.length; i < len; i++) {\r\n\t\t\t\tthis._off(types[i], fn, context);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn this;\r\n\t},\r\n\r\n\t// attach listener (without syntactic sugar now)\r\n\t_on: function (type, fn, context) {\r\n\t\tthis._events = this._events || {};\r\n\r\n\t\t/* get/init listeners for type */\r\n\t\tvar typeListeners = this._events[type];\r\n\t\tif (!typeListeners) {\r\n\t\t\ttypeListeners = [];\r\n\t\t\tthis._events[type] = typeListeners;\r\n\t\t}\r\n\r\n\t\tif (context === this) {\r\n\t\t\t// Less memory footprint.\r\n\t\t\tcontext = undefined;\r\n\t\t}\r\n\t\tvar newListener = {fn: fn, ctx: context},\r\n\t\t listeners = typeListeners;\r\n\r\n\t\t// check if fn already there\r\n\t\tfor (var i = 0, len = listeners.length; i < len; i++) {\r\n\t\t\tif (listeners[i].fn === fn && listeners[i].ctx === context) {\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tlisteners.push(newListener);\r\n\t},\r\n\r\n\t_off: function (type, fn, context) {\r\n\t\tvar listeners,\r\n\t\t i,\r\n\t\t len;\r\n\r\n\t\tif (!this._events) { return; }\r\n\r\n\t\tlisteners = this._events[type];\r\n\r\n\t\tif (!listeners) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tif (!fn) {\r\n\t\t\t// Set all removed listeners to noop so they are not called if remove happens in fire\r\n\t\t\tfor (i = 0, len = listeners.length; i < len; i++) {\r\n\t\t\t\tlisteners[i].fn = Util.falseFn;\r\n\t\t\t}\r\n\t\t\t// clear all listeners for a type if function isn't specified\r\n\t\t\tdelete this._events[type];\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tif (context === this) {\r\n\t\t\tcontext = undefined;\r\n\t\t}\r\n\r\n\t\tif (listeners) {\r\n\r\n\t\t\t// find fn and remove it\r\n\t\t\tfor (i = 0, len = listeners.length; i < len; i++) {\r\n\t\t\t\tvar l = listeners[i];\r\n\t\t\t\tif (l.ctx !== context) { continue; }\r\n\t\t\t\tif (l.fn === fn) {\r\n\r\n\t\t\t\t\t// set the removed listener to noop so that's not called if remove happens in fire\r\n\t\t\t\t\tl.fn = Util.falseFn;\r\n\r\n\t\t\t\t\tif (this._firingCount) {\r\n\t\t\t\t\t\t/* copy array in case events are being fired */\r\n\t\t\t\t\t\tthis._events[type] = listeners = listeners.slice();\r\n\t\t\t\t\t}\r\n\t\t\t\t\tlisteners.splice(i, 1);\r\n\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t},\r\n\r\n\t// @method fire(type: String, data?: Object, propagate?: Boolean): this\r\n\t// Fires an event of the specified type. You can optionally provide an data\r\n\t// object — the first argument of the listener function will contain its\r\n\t// properties. The event can optionally be propagated to event parents.\r\n\tfire: function (type, data, propagate) {\r\n\t\tif (!this.listens(type, propagate)) { return this; }\r\n\r\n\t\tvar event = Util.extend({}, data, {\r\n\t\t\ttype: type,\r\n\t\t\ttarget: this,\r\n\t\t\tsourceTarget: data && data.sourceTarget || this\r\n\t\t});\r\n\r\n\t\tif (this._events) {\r\n\t\t\tvar listeners = this._events[type];\r\n\r\n\t\t\tif (listeners) {\r\n\t\t\t\tthis._firingCount = (this._firingCount + 1) || 1;\r\n\t\t\t\tfor (var i = 0, len = listeners.length; i < len; i++) {\r\n\t\t\t\t\tvar l = listeners[i];\r\n\t\t\t\t\tl.fn.call(l.ctx || this, event);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tthis._firingCount--;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (propagate) {\r\n\t\t\t// propagate the event to parents (set with addEventParent)\r\n\t\t\tthis._propagateEvent(event);\r\n\t\t}\r\n\r\n\t\treturn this;\r\n\t},\r\n\r\n\t// @method listens(type: String): Boolean\r\n\t// Returns `true` if a particular event type has any listeners attached to it.\r\n\tlistens: function (type, propagate) {\r\n\t\tvar listeners = this._events && this._events[type];\r\n\t\tif (listeners && listeners.length) { return true; }\r\n\r\n\t\tif (propagate) {\r\n\t\t\t// also check parents for listeners if event propagates\r\n\t\t\tfor (var id in this._eventParents) {\r\n\t\t\t\tif (this._eventParents[id].listens(type, propagate)) { return true; }\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn false;\r\n\t},\r\n\r\n\t// @method once(…): this\r\n\t// Behaves as [`on(…)`](#evented-on), except the listener will only get fired once and then removed.\r\n\tonce: function (types, fn, context) {\r\n\r\n\t\tif (typeof types === 'object') {\r\n\t\t\tfor (var type in types) {\r\n\t\t\t\tthis.once(type, types[type], fn);\r\n\t\t\t}\r\n\t\t\treturn this;\r\n\t\t}\r\n\r\n\t\tvar handler = Util.bind(function () {\r\n\t\t\tthis\r\n\t\t\t .off(types, fn, context)\r\n\t\t\t .off(types, handler, context);\r\n\t\t}, this);\r\n\r\n\t\t// add a listener that's executed once and removed after that\r\n\t\treturn this\r\n\t\t .on(types, fn, context)\r\n\t\t .on(types, handler, context);\r\n\t},\r\n\r\n\t// @method addEventParent(obj: Evented): this\r\n\t// Adds an event parent - an `Evented` that will receive propagated events\r\n\taddEventParent: function (obj) {\r\n\t\tthis._eventParents = this._eventParents || {};\r\n\t\tthis._eventParents[Util.stamp(obj)] = obj;\r\n\t\treturn this;\r\n\t},\r\n\r\n\t// @method removeEventParent(obj: Evented): this\r\n\t// Removes an event parent, so it will stop receiving propagated events\r\n\tremoveEventParent: function (obj) {\r\n\t\tif (this._eventParents) {\r\n\t\t\tdelete this._eventParents[Util.stamp(obj)];\r\n\t\t}\r\n\t\treturn this;\r\n\t},\r\n\r\n\t_propagateEvent: function (e) {\r\n\t\tfor (var id in this._eventParents) {\r\n\t\t\tthis._eventParents[id].fire(e.type, Util.extend({\r\n\t\t\t\tlayer: e.target,\r\n\t\t\t\tpropagatedFrom: e.target\r\n\t\t\t}, e), true);\r\n\t\t}\r\n\t}\r\n};\r\n\r\n// aliases; we should ditch those eventually\r\n\r\n// @method addEventListener(…): this\r\n// Alias to [`on(…)`](#evented-on)\r\nEvents.addEventListener = Events.on;\r\n\r\n// @method removeEventListener(…): this\r\n// Alias to [`off(…)`](#evented-off)\r\n\r\n// @method clearAllEventListeners(…): this\r\n// Alias to [`off()`](#evented-off)\r\nEvents.removeEventListener = Events.clearAllEventListeners = Events.off;\r\n\r\n// @method addOneTimeEventListener(…): this\r\n// Alias to [`once(…)`](#evented-once)\r\nEvents.addOneTimeEventListener = Events.once;\r\n\r\n// @method fireEvent(…): this\r\n// Alias to [`fire(…)`](#evented-fire)\r\nEvents.fireEvent = Events.fire;\r\n\r\n// @method hasEventListeners(…): Boolean\r\n// Alias to [`listens(…)`](#evented-listens)\r\nEvents.hasEventListeners = Events.listens;\r\n\r\nexport var Evented = Class.extend(Events);\r\n","import {isArray, formatNum} from '../core/Util';\r\n\r\n/*\r\n * @class Point\r\n * @aka L.Point\r\n *\r\n * Represents a point with `x` and `y` coordinates in pixels.\r\n *\r\n * @example\r\n *\r\n * ```js\r\n * var point = L.point(200, 300);\r\n * ```\r\n *\r\n * All Leaflet methods and options that accept `Point` objects also accept them in a simple Array form (unless noted otherwise), so these lines are equivalent:\r\n *\r\n * ```js\r\n * map.panBy([200, 300]);\r\n * map.panBy(L.point(200, 300));\r\n * ```\r\n *\r\n * Note that `Point` does not inherit from Leafet's `Class` object,\r\n * which means new classes can't inherit from it, and new methods\r\n * can't be added to it with the `include` function.\r\n */\r\n\r\nexport function Point(x, y, round) {\r\n\t// @property x: Number; The `x` coordinate of the point\r\n\tthis.x = (round ? Math.round(x) : x);\r\n\t// @property y: Number; The `y` coordinate of the point\r\n\tthis.y = (round ? Math.round(y) : y);\r\n}\r\n\r\nvar trunc = Math.trunc || function (v) {\r\n\treturn v > 0 ? Math.floor(v) : Math.ceil(v);\r\n};\r\n\r\nPoint.prototype = {\r\n\r\n\t// @method clone(): Point\r\n\t// Returns a copy of the current point.\r\n\tclone: function () {\r\n\t\treturn new Point(this.x, this.y);\r\n\t},\r\n\r\n\t// @method add(otherPoint: Point): Point\r\n\t// Returns the result of addition of the current and the given points.\r\n\tadd: function (point) {\r\n\t\t// non-destructive, returns a new point\r\n\t\treturn this.clone()._add(toPoint(point));\r\n\t},\r\n\r\n\t_add: function (point) {\r\n\t\t// destructive, used directly for performance in situations where it's safe to modify existing point\r\n\t\tthis.x += point.x;\r\n\t\tthis.y += point.y;\r\n\t\treturn this;\r\n\t},\r\n\r\n\t// @method subtract(otherPoint: Point): Point\r\n\t// Returns the result of subtraction of the given point from the current.\r\n\tsubtract: function (point) {\r\n\t\treturn this.clone()._subtract(toPoint(point));\r\n\t},\r\n\r\n\t_subtract: function (point) {\r\n\t\tthis.x -= point.x;\r\n\t\tthis.y -= point.y;\r\n\t\treturn this;\r\n\t},\r\n\r\n\t// @method divideBy(num: Number): Point\r\n\t// Returns the result of division of the current point by the given number.\r\n\tdivideBy: function (num) {\r\n\t\treturn this.clone()._divideBy(num);\r\n\t},\r\n\r\n\t_divideBy: function (num) {\r\n\t\tthis.x /= num;\r\n\t\tthis.y /= num;\r\n\t\treturn this;\r\n\t},\r\n\r\n\t// @method multiplyBy(num: Number): Point\r\n\t// Returns the result of multiplication of the current point by the given number.\r\n\tmultiplyBy: function (num) {\r\n\t\treturn this.clone()._multiplyBy(num);\r\n\t},\r\n\r\n\t_multiplyBy: function (num) {\r\n\t\tthis.x *= num;\r\n\t\tthis.y *= num;\r\n\t\treturn this;\r\n\t},\r\n\r\n\t// @method scaleBy(scale: Point): Point\r\n\t// Multiply each coordinate of the current point by each coordinate of\r\n\t// `scale`. In linear algebra terms, multiply the point by the\r\n\t// [scaling matrix](https://en.wikipedia.org/wiki/Scaling_%28geometry%29#Matrix_representation)\r\n\t// defined by `scale`.\r\n\tscaleBy: function (point) {\r\n\t\treturn new Point(this.x * point.x, this.y * point.y);\r\n\t},\r\n\r\n\t// @method unscaleBy(scale: Point): Point\r\n\t// Inverse of `scaleBy`. Divide each coordinate of the current point by\r\n\t// each coordinate of `scale`.\r\n\tunscaleBy: function (point) {\r\n\t\treturn new Point(this.x / point.x, this.y / point.y);\r\n\t},\r\n\r\n\t// @method round(): Point\r\n\t// Returns a copy of the current point with rounded coordinates.\r\n\tround: function () {\r\n\t\treturn this.clone()._round();\r\n\t},\r\n\r\n\t_round: function () {\r\n\t\tthis.x = Math.round(this.x);\r\n\t\tthis.y = Math.round(this.y);\r\n\t\treturn this;\r\n\t},\r\n\r\n\t// @method floor(): Point\r\n\t// Returns a copy of the current point with floored coordinates (rounded down).\r\n\tfloor: function () {\r\n\t\treturn this.clone()._floor();\r\n\t},\r\n\r\n\t_floor: function () {\r\n\t\tthis.x = Math.floor(this.x);\r\n\t\tthis.y = Math.floor(this.y);\r\n\t\treturn this;\r\n\t},\r\n\r\n\t// @method ceil(): Point\r\n\t// Returns a copy of the current point with ceiled coordinates (rounded up).\r\n\tceil: function () {\r\n\t\treturn this.clone()._ceil();\r\n\t},\r\n\r\n\t_ceil: function () {\r\n\t\tthis.x = Math.ceil(this.x);\r\n\t\tthis.y = Math.ceil(this.y);\r\n\t\treturn this;\r\n\t},\r\n\r\n\t// @method trunc(): Point\r\n\t// Returns a copy of the current point with truncated coordinates (rounded towards zero).\r\n\ttrunc: function () {\r\n\t\treturn this.clone()._trunc();\r\n\t},\r\n\r\n\t_trunc: function () {\r\n\t\tthis.x = trunc(this.x);\r\n\t\tthis.y = trunc(this.y);\r\n\t\treturn this;\r\n\t},\r\n\r\n\t// @method distanceTo(otherPoint: Point): Number\r\n\t// Returns the cartesian distance between the current and the given points.\r\n\tdistanceTo: function (point) {\r\n\t\tpoint = toPoint(point);\r\n\r\n\t\tvar x = point.x - this.x,\r\n\t\t y = point.y - this.y;\r\n\r\n\t\treturn Math.sqrt(x * x + y * y);\r\n\t},\r\n\r\n\t// @method equals(otherPoint: Point): Boolean\r\n\t// Returns `true` if the given point has the same coordinates.\r\n\tequals: function (point) {\r\n\t\tpoint = toPoint(point);\r\n\r\n\t\treturn point.x === this.x &&\r\n\t\t point.y === this.y;\r\n\t},\r\n\r\n\t// @method contains(otherPoint: Point): Boolean\r\n\t// Returns `true` if both coordinates of the given point are less than the corresponding current point coordinates (in absolute values).\r\n\tcontains: function (point) {\r\n\t\tpoint = toPoint(point);\r\n\r\n\t\treturn Math.abs(point.x) <= Math.abs(this.x) &&\r\n\t\t Math.abs(point.y) <= Math.abs(this.y);\r\n\t},\r\n\r\n\t// @method toString(): String\r\n\t// Returns a string representation of the point for debugging purposes.\r\n\ttoString: function () {\r\n\t\treturn 'Point(' +\r\n\t\t formatNum(this.x) + ', ' +\r\n\t\t formatNum(this.y) + ')';\r\n\t}\r\n};\r\n\r\n// @factory L.point(x: Number, y: Number, round?: Boolean)\r\n// Creates a Point object with the given `x` and `y` coordinates. If optional `round` is set to true, rounds the `x` and `y` values.\r\n\r\n// @alternative\r\n// @factory L.point(coords: Number[])\r\n// Expects an array of the form `[x, y]` instead.\r\n\r\n// @alternative\r\n// @factory L.point(coords: Object)\r\n// Expects a plain object of the form `{x: Number, y: Number}` instead.\r\nexport function toPoint(x, y, round) {\r\n\tif (x instanceof Point) {\r\n\t\treturn x;\r\n\t}\r\n\tif (isArray(x)) {\r\n\t\treturn new Point(x[0], x[1]);\r\n\t}\r\n\tif (x === undefined || x === null) {\r\n\t\treturn x;\r\n\t}\r\n\tif (typeof x === 'object' && 'x' in x && 'y' in x) {\r\n\t\treturn new Point(x.x, x.y);\r\n\t}\r\n\treturn new Point(x, y, round);\r\n}\r\n","import {Point, toPoint} from './Point';\r\n\r\n/*\r\n * @class Bounds\r\n * @aka L.Bounds\r\n *\r\n * Represents a rectangular area in pixel coordinates.\r\n *\r\n * @example\r\n *\r\n * ```js\r\n * var p1 = L.point(10, 10),\r\n * p2 = L.point(40, 60),\r\n * bounds = L.bounds(p1, p2);\r\n * ```\r\n *\r\n * All Leaflet methods that accept `Bounds` objects also accept them in a simple Array form (unless noted otherwise), so the bounds example above can be passed like this:\r\n *\r\n * ```js\r\n * otherBounds.intersects([[10, 10], [40, 60]]);\r\n * ```\r\n *\r\n * Note that `Bounds` does not inherit from Leafet's `Class` object,\r\n * which means new classes can't inherit from it, and new methods\r\n * can't be added to it with the `include` function.\r\n */\r\n\r\nexport function Bounds(a, b) {\r\n\tif (!a) { return; }\r\n\r\n\tvar points = b ? [a, b] : a;\r\n\r\n\tfor (var i = 0, len = points.length; i < len; i++) {\r\n\t\tthis.extend(points[i]);\r\n\t}\r\n}\r\n\r\nBounds.prototype = {\r\n\t// @method extend(point: Point): this\r\n\t// Extends the bounds to contain the given point.\r\n\textend: function (point) { // (Point)\r\n\t\tpoint = toPoint(point);\r\n\r\n\t\t// @property min: Point\r\n\t\t// The top left corner of the rectangle.\r\n\t\t// @property max: Point\r\n\t\t// The bottom right corner of the rectangle.\r\n\t\tif (!this.min && !this.max) {\r\n\t\t\tthis.min = point.clone();\r\n\t\t\tthis.max = point.clone();\r\n\t\t} else {\r\n\t\t\tthis.min.x = Math.min(point.x, this.min.x);\r\n\t\t\tthis.max.x = Math.max(point.x, this.max.x);\r\n\t\t\tthis.min.y = Math.min(point.y, this.min.y);\r\n\t\t\tthis.max.y = Math.max(point.y, this.max.y);\r\n\t\t}\r\n\t\treturn this;\r\n\t},\r\n\r\n\t// @method getCenter(round?: Boolean): Point\r\n\t// Returns the center point of the bounds.\r\n\tgetCenter: function (round) {\r\n\t\treturn new Point(\r\n\t\t (this.min.x + this.max.x) / 2,\r\n\t\t (this.min.y + this.max.y) / 2, round);\r\n\t},\r\n\r\n\t// @method getBottomLeft(): Point\r\n\t// Returns the bottom-left point of the bounds.\r\n\tgetBottomLeft: function () {\r\n\t\treturn new Point(this.min.x, this.max.y);\r\n\t},\r\n\r\n\t// @method getTopRight(): Point\r\n\t// Returns the top-right point of the bounds.\r\n\tgetTopRight: function () { // -> Point\r\n\t\treturn new Point(this.max.x, this.min.y);\r\n\t},\r\n\r\n\t// @method getTopLeft(): Point\r\n\t// Returns the top-left point of the bounds (i.e. [`this.min`](#bounds-min)).\r\n\tgetTopLeft: function () {\r\n\t\treturn this.min; // left, top\r\n\t},\r\n\r\n\t// @method getBottomRight(): Point\r\n\t// Returns the bottom-right point of the bounds (i.e. [`this.max`](#bounds-max)).\r\n\tgetBottomRight: function () {\r\n\t\treturn this.max; // right, bottom\r\n\t},\r\n\r\n\t// @method getSize(): Point\r\n\t// Returns the size of the given bounds\r\n\tgetSize: function () {\r\n\t\treturn this.max.subtract(this.min);\r\n\t},\r\n\r\n\t// @method contains(otherBounds: Bounds): Boolean\r\n\t// Returns `true` if the rectangle contains the given one.\r\n\t// @alternative\r\n\t// @method contains(point: Point): Boolean\r\n\t// Returns `true` if the rectangle contains the given point.\r\n\tcontains: function (obj) {\r\n\t\tvar min, max;\r\n\r\n\t\tif (typeof obj[0] === 'number' || obj instanceof Point) {\r\n\t\t\tobj = toPoint(obj);\r\n\t\t} else {\r\n\t\t\tobj = toBounds(obj);\r\n\t\t}\r\n\r\n\t\tif (obj instanceof Bounds) {\r\n\t\t\tmin = obj.min;\r\n\t\t\tmax = obj.max;\r\n\t\t} else {\r\n\t\t\tmin = max = obj;\r\n\t\t}\r\n\r\n\t\treturn (min.x >= this.min.x) &&\r\n\t\t (max.x <= this.max.x) &&\r\n\t\t (min.y >= this.min.y) &&\r\n\t\t (max.y <= this.max.y);\r\n\t},\r\n\r\n\t// @method intersects(otherBounds: Bounds): Boolean\r\n\t// Returns `true` if the rectangle intersects the given bounds. Two bounds\r\n\t// intersect if they have at least one point in common.\r\n\tintersects: function (bounds) { // (Bounds) -> Boolean\r\n\t\tbounds = toBounds(bounds);\r\n\r\n\t\tvar min = this.min,\r\n\t\t max = this.max,\r\n\t\t min2 = bounds.min,\r\n\t\t max2 = bounds.max,\r\n\t\t xIntersects = (max2.x >= min.x) && (min2.x <= max.x),\r\n\t\t yIntersects = (max2.y >= min.y) && (min2.y <= max.y);\r\n\r\n\t\treturn xIntersects && yIntersects;\r\n\t},\r\n\r\n\t// @method overlaps(otherBounds: Bounds): Boolean\r\n\t// Returns `true` if the rectangle overlaps the given bounds. Two bounds\r\n\t// overlap if their intersection is an area.\r\n\toverlaps: function (bounds) { // (Bounds) -> Boolean\r\n\t\tbounds = toBounds(bounds);\r\n\r\n\t\tvar min = this.min,\r\n\t\t max = this.max,\r\n\t\t min2 = bounds.min,\r\n\t\t max2 = bounds.max,\r\n\t\t xOverlaps = (max2.x > min.x) && (min2.x < max.x),\r\n\t\t yOverlaps = (max2.y > min.y) && (min2.y < max.y);\r\n\r\n\t\treturn xOverlaps && yOverlaps;\r\n\t},\r\n\r\n\tisValid: function () {\r\n\t\treturn !!(this.min && this.max);\r\n\t}\r\n};\r\n\r\n\r\n// @factory L.bounds(corner1: Point, corner2: Point)\r\n// Creates a Bounds object from two corners coordinate pairs.\r\n// @alternative\r\n// @factory L.bounds(points: Point[])\r\n// Creates a Bounds object from the given array of points.\r\nexport function toBounds(a, b) {\r\n\tif (!a || a instanceof Bounds) {\r\n\t\treturn a;\r\n\t}\r\n\treturn new Bounds(a, b);\r\n}\r\n","import {LatLng, toLatLng} from './LatLng';\r\n\r\n/*\r\n * @class LatLngBounds\r\n * @aka L.LatLngBounds\r\n *\r\n * Represents a rectangular geographical area on a map.\r\n *\r\n * @example\r\n *\r\n * ```js\r\n * var corner1 = L.latLng(40.712, -74.227),\r\n * corner2 = L.latLng(40.774, -74.125),\r\n * bounds = L.latLngBounds(corner1, corner2);\r\n * ```\r\n *\r\n * All Leaflet methods that accept LatLngBounds objects also accept them in a simple Array form (unless noted otherwise), so the bounds example above can be passed like this:\r\n *\r\n * ```js\r\n * map.fitBounds([\r\n * \t[40.712, -74.227],\r\n * \t[40.774, -74.125]\r\n * ]);\r\n * ```\r\n *\r\n * Caution: if the area crosses the antimeridian (often confused with the International Date Line), you must specify corners _outside_ the [-180, 180] degrees longitude range.\r\n *\r\n * Note that `LatLngBounds` does not inherit from Leafet's `Class` object,\r\n * which means new classes can't inherit from it, and new methods\r\n * can't be added to it with the `include` function.\r\n */\r\n\r\nexport function LatLngBounds(corner1, corner2) { // (LatLng, LatLng) or (LatLng[])\r\n\tif (!corner1) { return; }\r\n\r\n\tvar latlngs = corner2 ? [corner1, corner2] : corner1;\r\n\r\n\tfor (var i = 0, len = latlngs.length; i < len; i++) {\r\n\t\tthis.extend(latlngs[i]);\r\n\t}\r\n}\r\n\r\nLatLngBounds.prototype = {\r\n\r\n\t// @method extend(latlng: LatLng): this\r\n\t// Extend the bounds to contain the given point\r\n\r\n\t// @alternative\r\n\t// @method extend(otherBounds: LatLngBounds): this\r\n\t// Extend the bounds to contain the given bounds\r\n\textend: function (obj) {\r\n\t\tvar sw = this._southWest,\r\n\t\t ne = this._northEast,\r\n\t\t sw2, ne2;\r\n\r\n\t\tif (obj instanceof LatLng) {\r\n\t\t\tsw2 = obj;\r\n\t\t\tne2 = obj;\r\n\r\n\t\t} else if (obj instanceof LatLngBounds) {\r\n\t\t\tsw2 = obj._southWest;\r\n\t\t\tne2 = obj._northEast;\r\n\r\n\t\t\tif (!sw2 || !ne2) { return this; }\r\n\r\n\t\t} else {\r\n\t\t\treturn obj ? this.extend(toLatLng(obj) || toLatLngBounds(obj)) : this;\r\n\t\t}\r\n\r\n\t\tif (!sw && !ne) {\r\n\t\t\tthis._southWest = new LatLng(sw2.lat, sw2.lng);\r\n\t\t\tthis._northEast = new LatLng(ne2.lat, ne2.lng);\r\n\t\t} else {\r\n\t\t\tsw.lat = Math.min(sw2.lat, sw.lat);\r\n\t\t\tsw.lng = Math.min(sw2.lng, sw.lng);\r\n\t\t\tne.lat = Math.max(ne2.lat, ne.lat);\r\n\t\t\tne.lng = Math.max(ne2.lng, ne.lng);\r\n\t\t}\r\n\r\n\t\treturn this;\r\n\t},\r\n\r\n\t// @method pad(bufferRatio: Number): LatLngBounds\r\n\t// Returns bounds created by extending or retracting the current bounds by a given ratio in each direction.\r\n\t// For example, a ratio of 0.5 extends the bounds by 50% in each direction.\r\n\t// Negative values will retract the bounds.\r\n\tpad: function (bufferRatio) {\r\n\t\tvar sw = this._southWest,\r\n\t\t ne = this._northEast,\r\n\t\t heightBuffer = Math.abs(sw.lat - ne.lat) * bufferRatio,\r\n\t\t widthBuffer = Math.abs(sw.lng - ne.lng) * bufferRatio;\r\n\r\n\t\treturn new LatLngBounds(\r\n\t\t new LatLng(sw.lat - heightBuffer, sw.lng - widthBuffer),\r\n\t\t new LatLng(ne.lat + heightBuffer, ne.lng + widthBuffer));\r\n\t},\r\n\r\n\t// @method getCenter(): LatLng\r\n\t// Returns the center point of the bounds.\r\n\tgetCenter: function () {\r\n\t\treturn new LatLng(\r\n\t\t (this._southWest.lat + this._northEast.lat) / 2,\r\n\t\t (this._southWest.lng + this._northEast.lng) / 2);\r\n\t},\r\n\r\n\t// @method getSouthWest(): LatLng\r\n\t// Returns the south-west point of the bounds.\r\n\tgetSouthWest: function () {\r\n\t\treturn this._southWest;\r\n\t},\r\n\r\n\t// @method getNorthEast(): LatLng\r\n\t// Returns the north-east point of the bounds.\r\n\tgetNorthEast: function () {\r\n\t\treturn this._northEast;\r\n\t},\r\n\r\n\t// @method getNorthWest(): LatLng\r\n\t// Returns the north-west point of the bounds.\r\n\tgetNorthWest: function () {\r\n\t\treturn new LatLng(this.getNorth(), this.getWest());\r\n\t},\r\n\r\n\t// @method getSouthEast(): LatLng\r\n\t// Returns the south-east point of the bounds.\r\n\tgetSouthEast: function () {\r\n\t\treturn new LatLng(this.getSouth(), this.getEast());\r\n\t},\r\n\r\n\t// @method getWest(): Number\r\n\t// Returns the west longitude of the bounds\r\n\tgetWest: function () {\r\n\t\treturn this._southWest.lng;\r\n\t},\r\n\r\n\t// @method getSouth(): Number\r\n\t// Returns the south latitude of the bounds\r\n\tgetSouth: function () {\r\n\t\treturn this._southWest.lat;\r\n\t},\r\n\r\n\t// @method getEast(): Number\r\n\t// Returns the east longitude of the bounds\r\n\tgetEast: function () {\r\n\t\treturn this._northEast.lng;\r\n\t},\r\n\r\n\t// @method getNorth(): Number\r\n\t// Returns the north latitude of the bounds\r\n\tgetNorth: function () {\r\n\t\treturn this._northEast.lat;\r\n\t},\r\n\r\n\t// @method contains(otherBounds: LatLngBounds): Boolean\r\n\t// Returns `true` if the rectangle contains the given one.\r\n\r\n\t// @alternative\r\n\t// @method contains (latlng: LatLng): Boolean\r\n\t// Returns `true` if the rectangle contains the given point.\r\n\tcontains: function (obj) { // (LatLngBounds) or (LatLng) -> Boolean\r\n\t\tif (typeof obj[0] === 'number' || obj instanceof LatLng || 'lat' in obj) {\r\n\t\t\tobj = toLatLng(obj);\r\n\t\t} else {\r\n\t\t\tobj = toLatLngBounds(obj);\r\n\t\t}\r\n\r\n\t\tvar sw = this._southWest,\r\n\t\t ne = this._northEast,\r\n\t\t sw2, ne2;\r\n\r\n\t\tif (obj instanceof LatLngBounds) {\r\n\t\t\tsw2 = obj.getSouthWest();\r\n\t\t\tne2 = obj.getNorthEast();\r\n\t\t} else {\r\n\t\t\tsw2 = ne2 = obj;\r\n\t\t}\r\n\r\n\t\treturn (sw2.lat >= sw.lat) && (ne2.lat <= ne.lat) &&\r\n\t\t (sw2.lng >= sw.lng) && (ne2.lng <= ne.lng);\r\n\t},\r\n\r\n\t// @method intersects(otherBounds: LatLngBounds): Boolean\r\n\t// Returns `true` if the rectangle intersects the given bounds. Two bounds intersect if they have at least one point in common.\r\n\tintersects: function (bounds) {\r\n\t\tbounds = toLatLngBounds(bounds);\r\n\r\n\t\tvar sw = this._southWest,\r\n\t\t ne = this._northEast,\r\n\t\t sw2 = bounds.getSouthWest(),\r\n\t\t ne2 = bounds.getNorthEast(),\r\n\r\n\t\t latIntersects = (ne2.lat >= sw.lat) && (sw2.lat <= ne.lat),\r\n\t\t lngIntersects = (ne2.lng >= sw.lng) && (sw2.lng <= ne.lng);\r\n\r\n\t\treturn latIntersects && lngIntersects;\r\n\t},\r\n\r\n\t// @method overlaps(otherBounds: Bounds): Boolean\r\n\t// Returns `true` if the rectangle overlaps the given bounds. Two bounds overlap if their intersection is an area.\r\n\toverlaps: function (bounds) {\r\n\t\tbounds = toLatLngBounds(bounds);\r\n\r\n\t\tvar sw = this._southWest,\r\n\t\t ne = this._northEast,\r\n\t\t sw2 = bounds.getSouthWest(),\r\n\t\t ne2 = bounds.getNorthEast(),\r\n\r\n\t\t latOverlaps = (ne2.lat > sw.lat) && (sw2.lat < ne.lat),\r\n\t\t lngOverlaps = (ne2.lng > sw.lng) && (sw2.lng < ne.lng);\r\n\r\n\t\treturn latOverlaps && lngOverlaps;\r\n\t},\r\n\r\n\t// @method toBBoxString(): String\r\n\t// Returns a string with bounding box coordinates in a 'southwest_lng,southwest_lat,northeast_lng,northeast_lat' format. Useful for sending requests to web services that return geo data.\r\n\ttoBBoxString: function () {\r\n\t\treturn [this.getWest(), this.getSouth(), this.getEast(), this.getNorth()].join(',');\r\n\t},\r\n\r\n\t// @method equals(otherBounds: LatLngBounds, maxMargin?: Number): Boolean\r\n\t// Returns `true` if the rectangle is equivalent (within a small margin of error) to the given bounds. The margin of error can be overridden by setting `maxMargin` to a small number.\r\n\tequals: function (bounds, maxMargin) {\r\n\t\tif (!bounds) { return false; }\r\n\r\n\t\tbounds = toLatLngBounds(bounds);\r\n\r\n\t\treturn this._southWest.equals(bounds.getSouthWest(), maxMargin) &&\r\n\t\t this._northEast.equals(bounds.getNorthEast(), maxMargin);\r\n\t},\r\n\r\n\t// @method isValid(): Boolean\r\n\t// Returns `true` if the bounds are properly initialized.\r\n\tisValid: function () {\r\n\t\treturn !!(this._southWest && this._northEast);\r\n\t}\r\n};\r\n\r\n// TODO International date line?\r\n\r\n// @factory L.latLngBounds(corner1: LatLng, corner2: LatLng)\r\n// Creates a `LatLngBounds` object by defining two diagonally opposite corners of the rectangle.\r\n\r\n// @alternative\r\n// @factory L.latLngBounds(latlngs: LatLng[])\r\n// Creates a `LatLngBounds` object defined by the geographical points it contains. Very useful for zooming the map to fit a particular set of locations with [`fitBounds`](#map-fitbounds).\r\nexport function toLatLngBounds(a, b) {\r\n\tif (a instanceof LatLngBounds) {\r\n\t\treturn a;\r\n\t}\r\n\treturn new LatLngBounds(a, b);\r\n}\r\n","import * as Util from '../core/Util';\r\nimport {Earth} from './crs/CRS.Earth';\r\nimport {toLatLngBounds} from './LatLngBounds';\r\n\r\n/* @class LatLng\r\n * @aka L.LatLng\r\n *\r\n * Represents a geographical point with a certain latitude and longitude.\r\n *\r\n * @example\r\n *\r\n * ```\r\n * var latlng = L.latLng(50.5, 30.5);\r\n * ```\r\n *\r\n * All Leaflet methods that accept LatLng objects also accept them in a simple Array form and simple object form (unless noted otherwise), so these lines are equivalent:\r\n *\r\n * ```\r\n * map.panTo([50, 30]);\r\n * map.panTo({lon: 30, lat: 50});\r\n * map.panTo({lat: 50, lng: 30});\r\n * map.panTo(L.latLng(50, 30));\r\n * ```\r\n *\r\n * Note that `LatLng` does not inherit from Leaflet's `Class` object,\r\n * which means new classes can't inherit from it, and new methods\r\n * can't be added to it with the `include` function.\r\n */\r\n\r\nexport function LatLng(lat, lng, alt) {\r\n\tif (isNaN(lat) || isNaN(lng)) {\r\n\t\tthrow new Error('Invalid LatLng object: (' + lat + ', ' + lng + ')');\r\n\t}\r\n\r\n\t// @property lat: Number\r\n\t// Latitude in degrees\r\n\tthis.lat = +lat;\r\n\r\n\t// @property lng: Number\r\n\t// Longitude in degrees\r\n\tthis.lng = +lng;\r\n\r\n\t// @property alt: Number\r\n\t// Altitude in meters (optional)\r\n\tif (alt !== undefined) {\r\n\t\tthis.alt = +alt;\r\n\t}\r\n}\r\n\r\nLatLng.prototype = {\r\n\t// @method equals(otherLatLng: LatLng, maxMargin?: Number): Boolean\r\n\t// Returns `true` if the given `LatLng` point is at the same position (within a small margin of error). The margin of error can be overridden by setting `maxMargin` to a small number.\r\n\tequals: function (obj, maxMargin) {\r\n\t\tif (!obj) { return false; }\r\n\r\n\t\tobj = toLatLng(obj);\r\n\r\n\t\tvar margin = Math.max(\r\n\t\t Math.abs(this.lat - obj.lat),\r\n\t\t Math.abs(this.lng - obj.lng));\r\n\r\n\t\treturn margin <= (maxMargin === undefined ? 1.0E-9 : maxMargin);\r\n\t},\r\n\r\n\t// @method toString(): String\r\n\t// Returns a string representation of the point (for debugging purposes).\r\n\ttoString: function (precision) {\r\n\t\treturn 'LatLng(' +\r\n\t\t Util.formatNum(this.lat, precision) + ', ' +\r\n\t\t Util.formatNum(this.lng, precision) + ')';\r\n\t},\r\n\r\n\t// @method distanceTo(otherLatLng: LatLng): Number\r\n\t// Returns the distance (in meters) to the given `LatLng` calculated using the [Spherical Law of Cosines](https://en.wikipedia.org/wiki/Spherical_law_of_cosines).\r\n\tdistanceTo: function (other) {\r\n\t\treturn Earth.distance(this, toLatLng(other));\r\n\t},\r\n\r\n\t// @method wrap(): LatLng\r\n\t// Returns a new `LatLng` object with the longitude wrapped so it's always between -180 and +180 degrees.\r\n\twrap: function () {\r\n\t\treturn Earth.wrapLatLng(this);\r\n\t},\r\n\r\n\t// @method toBounds(sizeInMeters: Number): LatLngBounds\r\n\t// Returns a new `LatLngBounds` object in which each boundary is `sizeInMeters/2` meters apart from the `LatLng`.\r\n\ttoBounds: function (sizeInMeters) {\r\n\t\tvar latAccuracy = 180 * sizeInMeters / 40075017,\r\n\t\t lngAccuracy = latAccuracy / Math.cos((Math.PI / 180) * this.lat);\r\n\r\n\t\treturn toLatLngBounds(\r\n\t\t [this.lat - latAccuracy, this.lng - lngAccuracy],\r\n\t\t [this.lat + latAccuracy, this.lng + lngAccuracy]);\r\n\t},\r\n\r\n\tclone: function () {\r\n\t\treturn new LatLng(this.lat, this.lng, this.alt);\r\n\t}\r\n};\r\n\r\n\r\n\r\n// @factory L.latLng(latitude: Number, longitude: Number, altitude?: Number): LatLng\r\n// Creates an object representing a geographical point with the given latitude and longitude (and optionally altitude).\r\n\r\n// @alternative\r\n// @factory L.latLng(coords: Array): LatLng\r\n// Expects an array of the form `[Number, Number]` or `[Number, Number, Number]` instead.\r\n\r\n// @alternative\r\n// @factory L.latLng(coords: Object): LatLng\r\n// Expects an plain object of the form `{lat: Number, lng: Number}` or `{lat: Number, lng: Number, alt: Number}` instead.\r\n\r\nexport function toLatLng(a, b, c) {\r\n\tif (a instanceof LatLng) {\r\n\t\treturn a;\r\n\t}\r\n\tif (Util.isArray(a) && typeof a[0] !== 'object') {\r\n\t\tif (a.length === 3) {\r\n\t\t\treturn new LatLng(a[0], a[1], a[2]);\r\n\t\t}\r\n\t\tif (a.length === 2) {\r\n\t\t\treturn new LatLng(a[0], a[1]);\r\n\t\t}\r\n\t\treturn null;\r\n\t}\r\n\tif (a === undefined || a === null) {\r\n\t\treturn a;\r\n\t}\r\n\tif (typeof a === 'object' && 'lat' in a) {\r\n\t\treturn new LatLng(a.lat, 'lng' in a ? a.lng : a.lon, a.alt);\r\n\t}\r\n\tif (b === undefined) {\r\n\t\treturn null;\r\n\t}\r\n\treturn new LatLng(a, b, c);\r\n}\r\n","\r\nimport {Bounds} from '../../geometry/Bounds';\r\nimport {LatLng} from '../LatLng';\r\nimport {LatLngBounds} from '../LatLngBounds';\r\nimport * as Util from '../../core/Util';\r\n\r\n/*\r\n * @namespace CRS\r\n * @crs L.CRS.Base\r\n * Object that defines coordinate reference systems for projecting\r\n * geographical points into pixel (screen) coordinates and back (and to\r\n * coordinates in other units for [WMS](https://en.wikipedia.org/wiki/Web_Map_Service) services). See\r\n * [spatial reference system](http://en.wikipedia.org/wiki/Coordinate_reference_system).\r\n *\r\n * Leaflet defines the most usual CRSs by default. If you want to use a\r\n * CRS not defined by default, take a look at the\r\n * [Proj4Leaflet](https://github.com/kartena/Proj4Leaflet) plugin.\r\n *\r\n * Note that the CRS instances do not inherit from Leafet's `Class` object,\r\n * and can't be instantiated. Also, new classes can't inherit from them,\r\n * and methods can't be added to them with the `include` function.\r\n */\r\n\r\nexport var CRS = {\r\n\t// @method latLngToPoint(latlng: LatLng, zoom: Number): Point\r\n\t// Projects geographical coordinates into pixel coordinates for a given zoom.\r\n\tlatLngToPoint: function (latlng, zoom) {\r\n\t\tvar projectedPoint = this.projection.project(latlng),\r\n\t\t scale = this.scale(zoom);\r\n\r\n\t\treturn this.transformation._transform(projectedPoint, scale);\r\n\t},\r\n\r\n\t// @method pointToLatLng(point: Point, zoom: Number): LatLng\r\n\t// The inverse of `latLngToPoint`. Projects pixel coordinates on a given\r\n\t// zoom into geographical coordinates.\r\n\tpointToLatLng: function (point, zoom) {\r\n\t\tvar scale = this.scale(zoom),\r\n\t\t untransformedPoint = this.transformation.untransform(point, scale);\r\n\r\n\t\treturn this.projection.unproject(untransformedPoint);\r\n\t},\r\n\r\n\t// @method project(latlng: LatLng): Point\r\n\t// Projects geographical coordinates into coordinates in units accepted for\r\n\t// this CRS (e.g. meters for EPSG:3857, for passing it to WMS services).\r\n\tproject: function (latlng) {\r\n\t\treturn this.projection.project(latlng);\r\n\t},\r\n\r\n\t// @method unproject(point: Point): LatLng\r\n\t// Given a projected coordinate returns the corresponding LatLng.\r\n\t// The inverse of `project`.\r\n\tunproject: function (point) {\r\n\t\treturn this.projection.unproject(point);\r\n\t},\r\n\r\n\t// @method scale(zoom: Number): Number\r\n\t// Returns the scale used when transforming projected coordinates into\r\n\t// pixel coordinates for a particular zoom. For example, it returns\r\n\t// `256 * 2^zoom` for Mercator-based CRS.\r\n\tscale: function (zoom) {\r\n\t\treturn 256 * Math.pow(2, zoom);\r\n\t},\r\n\r\n\t// @method zoom(scale: Number): Number\r\n\t// Inverse of `scale()`, returns the zoom level corresponding to a scale\r\n\t// factor of `scale`.\r\n\tzoom: function (scale) {\r\n\t\treturn Math.log(scale / 256) / Math.LN2;\r\n\t},\r\n\r\n\t// @method getProjectedBounds(zoom: Number): Bounds\r\n\t// Returns the projection's bounds scaled and transformed for the provided `zoom`.\r\n\tgetProjectedBounds: function (zoom) {\r\n\t\tif (this.infinite) { return null; }\r\n\r\n\t\tvar b = this.projection.bounds,\r\n\t\t s = this.scale(zoom),\r\n\t\t min = this.transformation.transform(b.min, s),\r\n\t\t max = this.transformation.transform(b.max, s);\r\n\r\n\t\treturn new Bounds(min, max);\r\n\t},\r\n\r\n\t// @method distance(latlng1: LatLng, latlng2: LatLng): Number\r\n\t// Returns the distance between two geographical coordinates.\r\n\r\n\t// @property code: String\r\n\t// Standard code name of the CRS passed into WMS services (e.g. `'EPSG:3857'`)\r\n\t//\r\n\t// @property wrapLng: Number[]\r\n\t// An array of two numbers defining whether the longitude (horizontal) coordinate\r\n\t// axis wraps around a given range and how. Defaults to `[-180, 180]` in most\r\n\t// geographical CRSs. If `undefined`, the longitude axis does not wrap around.\r\n\t//\r\n\t// @property wrapLat: Number[]\r\n\t// Like `wrapLng`, but for the latitude (vertical) axis.\r\n\r\n\t// wrapLng: [min, max],\r\n\t// wrapLat: [min, max],\r\n\r\n\t// @property infinite: Boolean\r\n\t// If true, the coordinate space will be unbounded (infinite in both axes)\r\n\tinfinite: false,\r\n\r\n\t// @method wrapLatLng(latlng: LatLng): LatLng\r\n\t// Returns a `LatLng` where lat and lng has been wrapped according to the\r\n\t// CRS's `wrapLat` and `wrapLng` properties, if they are outside the CRS's bounds.\r\n\twrapLatLng: function (latlng) {\r\n\t\tvar lng = this.wrapLng ? Util.wrapNum(latlng.lng, this.wrapLng, true) : latlng.lng,\r\n\t\t lat = this.wrapLat ? Util.wrapNum(latlng.lat, this.wrapLat, true) : latlng.lat,\r\n\t\t alt = latlng.alt;\r\n\r\n\t\treturn new LatLng(lat, lng, alt);\r\n\t},\r\n\r\n\t// @method wrapLatLngBounds(bounds: LatLngBounds): LatLngBounds\r\n\t// Returns a `LatLngBounds` with the same size as the given one, ensuring\r\n\t// that its center is within the CRS's bounds.\r\n\t// Only accepts actual `L.LatLngBounds` instances, not arrays.\r\n\twrapLatLngBounds: function (bounds) {\r\n\t\tvar center = bounds.getCenter(),\r\n\t\t newCenter = this.wrapLatLng(center),\r\n\t\t latShift = center.lat - newCenter.lat,\r\n\t\t lngShift = center.lng - newCenter.lng;\r\n\r\n\t\tif (latShift === 0 && lngShift === 0) {\r\n\t\t\treturn bounds;\r\n\t\t}\r\n\r\n\t\tvar sw = bounds.getSouthWest(),\r\n\t\t ne = bounds.getNorthEast(),\r\n\t\t newSw = new LatLng(sw.lat - latShift, sw.lng - lngShift),\r\n\t\t newNe = new LatLng(ne.lat - latShift, ne.lng - lngShift);\r\n\r\n\t\treturn new LatLngBounds(newSw, newNe);\r\n\t}\r\n};\r\n","import {CRS} from './CRS';\nimport * as Util from '../../core/Util';\n\n/*\n * @namespace CRS\n * @crs L.CRS.Earth\n *\n * Serves as the base for CRS that are global such that they cover the earth.\n * Can only be used as the base for other CRS and cannot be used directly,\n * since it does not have a `code`, `projection` or `transformation`. `distance()` returns\n * meters.\n */\n\nexport var Earth = Util.extend({}, CRS, {\n\twrapLng: [-180, 180],\n\n\t// Mean Earth Radius, as recommended for use by\n\t// the International Union of Geodesy and Geophysics,\n\t// see http://rosettacode.org/wiki/Haversine_formula\n\tR: 6371000,\n\n\t// distance between two geographical points using spherical law of cosines approximation\n\tdistance: function (latlng1, latlng2) {\n\t\tvar rad = Math.PI / 180,\n\t\t lat1 = latlng1.lat * rad,\n\t\t lat2 = latlng2.lat * rad,\n\t\t sinDLat = Math.sin((latlng2.lat - latlng1.lat) * rad / 2),\n\t\t sinDLon = Math.sin((latlng2.lng - latlng1.lng) * rad / 2),\n\t\t a = sinDLat * sinDLat + Math.cos(lat1) * Math.cos(lat2) * sinDLon * sinDLon,\n\t\t c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));\n\t\treturn this.R * c;\n\t}\n});\n","import {LatLng} from '../LatLng';\r\nimport {Bounds} from '../../geometry/Bounds';\r\nimport {Point} from '../../geometry/Point';\r\n\r\n/*\r\n * @namespace Projection\r\n * @projection L.Projection.SphericalMercator\r\n *\r\n * Spherical Mercator projection — the most common projection for online maps,\r\n * used by almost all free and commercial tile providers. Assumes that Earth is\r\n * a sphere. Used by the `EPSG:3857` CRS.\r\n */\r\n\r\nvar earthRadius = 6378137;\r\n\r\nexport var SphericalMercator = {\r\n\r\n\tR: earthRadius,\r\n\tMAX_LATITUDE: 85.0511287798,\r\n\r\n\tproject: function (latlng) {\r\n\t\tvar d = Math.PI / 180,\r\n\t\t max = this.MAX_LATITUDE,\r\n\t\t lat = Math.max(Math.min(max, latlng.lat), -max),\r\n\t\t sin = Math.sin(lat * d);\r\n\r\n\t\treturn new Point(\r\n\t\t\tthis.R * latlng.lng * d,\r\n\t\t\tthis.R * Math.log((1 + sin) / (1 - sin)) / 2);\r\n\t},\r\n\r\n\tunproject: function (point) {\r\n\t\tvar d = 180 / Math.PI;\r\n\r\n\t\treturn new LatLng(\r\n\t\t\t(2 * Math.atan(Math.exp(point.y / this.R)) - (Math.PI / 2)) * d,\r\n\t\t\tpoint.x * d / this.R);\r\n\t},\r\n\r\n\tbounds: (function () {\r\n\t\tvar d = earthRadius * Math.PI;\r\n\t\treturn new Bounds([-d, -d], [d, d]);\r\n\t})()\r\n};\r\n","import {Point} from './Point';\r\nimport * as Util from '../core/Util';\r\n\r\n/*\r\n * @class Transformation\r\n * @aka L.Transformation\r\n *\r\n * Represents an affine transformation: a set of coefficients `a`, `b`, `c`, `d`\r\n * for transforming a point of a form `(x, y)` into `(a*x + b, c*y + d)` and doing\r\n * the reverse. Used by Leaflet in its projections code.\r\n *\r\n * @example\r\n *\r\n * ```js\r\n * var transformation = L.transformation(2, 5, -1, 10),\r\n * \tp = L.point(1, 2),\r\n * \tp2 = transformation.transform(p), // L.point(7, 8)\r\n * \tp3 = transformation.untransform(p2); // L.point(1, 2)\r\n * ```\r\n */\r\n\r\n\r\n// factory new L.Transformation(a: Number, b: Number, c: Number, d: Number)\r\n// Creates a `Transformation` object with the given coefficients.\r\nexport function Transformation(a, b, c, d) {\r\n\tif (Util.isArray(a)) {\r\n\t\t// use array properties\r\n\t\tthis._a = a[0];\r\n\t\tthis._b = a[1];\r\n\t\tthis._c = a[2];\r\n\t\tthis._d = a[3];\r\n\t\treturn;\r\n\t}\r\n\tthis._a = a;\r\n\tthis._b = b;\r\n\tthis._c = c;\r\n\tthis._d = d;\r\n}\r\n\r\nTransformation.prototype = {\r\n\t// @method transform(point: Point, scale?: Number): Point\r\n\t// Returns a transformed point, optionally multiplied by the given scale.\r\n\t// Only accepts actual `L.Point` instances, not arrays.\r\n\ttransform: function (point, scale) { // (Point, Number) -> Point\r\n\t\treturn this._transform(point.clone(), scale);\r\n\t},\r\n\r\n\t// destructive transform (faster)\r\n\t_transform: function (point, scale) {\r\n\t\tscale = scale || 1;\r\n\t\tpoint.x = scale * (this._a * point.x + this._b);\r\n\t\tpoint.y = scale * (this._c * point.y + this._d);\r\n\t\treturn point;\r\n\t},\r\n\r\n\t// @method untransform(point: Point, scale?: Number): Point\r\n\t// Returns the reverse transformation of the given point, optionally divided\r\n\t// by the given scale. Only accepts actual `L.Point` instances, not arrays.\r\n\tuntransform: function (point, scale) {\r\n\t\tscale = scale || 1;\r\n\t\treturn new Point(\r\n\t\t (point.x / scale - this._b) / this._a,\r\n\t\t (point.y / scale - this._d) / this._c);\r\n\t}\r\n};\r\n\r\n// factory L.transformation(a: Number, b: Number, c: Number, d: Number)\r\n\r\n// @factory L.transformation(a: Number, b: Number, c: Number, d: Number)\r\n// Instantiates a Transformation object with the given coefficients.\r\n\r\n// @alternative\r\n// @factory L.transformation(coefficients: Array): Transformation\r\n// Expects an coefficients array of the form\r\n// `[a: Number, b: Number, c: Number, d: Number]`.\r\n\r\nexport function toTransformation(a, b, c, d) {\r\n\treturn new Transformation(a, b, c, d);\r\n}\r\n","import {Earth} from './CRS.Earth';\r\nimport {SphericalMercator} from '../projection/Projection.SphericalMercator';\r\nimport {toTransformation} from '../../geometry/Transformation';\r\nimport * as Util from '../../core/Util';\r\n\r\n/*\r\n * @namespace CRS\r\n * @crs L.CRS.EPSG3857\r\n *\r\n * The most common CRS for online maps, used by almost all free and commercial\r\n * tile providers. Uses Spherical Mercator projection. Set in by default in\r\n * Map's `crs` option.\r\n */\r\n\r\nexport var EPSG3857 = Util.extend({}, Earth, {\r\n\tcode: 'EPSG:3857',\r\n\tprojection: SphericalMercator,\r\n\r\n\ttransformation: (function () {\r\n\t\tvar scale = 0.5 / (Math.PI * SphericalMercator.R);\r\n\t\treturn toTransformation(scale, 0.5, -scale, 0.5);\r\n\t}())\r\n});\r\n\r\nexport var EPSG900913 = Util.extend({}, EPSG3857, {\r\n\tcode: 'EPSG:900913'\r\n});\r\n","import * as Browser from '../../core/Browser';\n\n// @namespace SVG; @section\n// There are several static functions which can be called without instantiating L.SVG:\n\n// @function create(name: String): SVGElement\n// Returns a instance of [SVGElement](https://developer.mozilla.org/docs/Web/API/SVGElement),\n// corresponding to the class name passed. For example, using 'line' will return\n// an instance of [SVGLineElement](https://developer.mozilla.org/docs/Web/API/SVGLineElement).\nexport function svgCreate(name) {\n\treturn document.createElementNS('http://www.w3.org/2000/svg', name);\n}\n\n// @function pointsToPath(rings: Point[], closed: Boolean): String\n// Generates a SVG path string for multiple rings, with each ring turning\n// into \"M..L..L..\" instructions\nexport function pointsToPath(rings, closed) {\n\tvar str = '',\n\ti, j, len, len2, points, p;\n\n\tfor (i = 0, len = rings.length; i < len; i++) {\n\t\tpoints = rings[i];\n\n\t\tfor (j = 0, len2 = points.length; j < len2; j++) {\n\t\t\tp = points[j];\n\t\t\tstr += (j ? 'L' : 'M') + p.x + ' ' + p.y;\n\t\t}\n\n\t\t// closes the ring for polygons; \"x\" is VML syntax\n\t\tstr += closed ? (Browser.svg ? 'z' : 'x') : '';\n\t}\n\n\t// SVG complains about empty path strings\n\treturn str || 'M0 0';\n}\n\n\n\n\n","import * as Util from './Util';\r\nimport {svgCreate} from '../layer/vector/SVG.Util';\r\n\r\n/*\r\n * @namespace Browser\r\n * @aka L.Browser\r\n *\r\n * A namespace with static properties for browser/feature detection used by Leaflet internally.\r\n *\r\n * @example\r\n *\r\n * ```js\r\n * if (L.Browser.ielt9) {\r\n * alert('Upgrade your browser, dude!');\r\n * }\r\n * ```\r\n */\r\n\r\nvar style = document.documentElement.style;\r\n\r\n// @property ie: Boolean; `true` for all Internet Explorer versions (not Edge).\r\nexport var ie = 'ActiveXObject' in window;\r\n\r\n// @property ielt9: Boolean; `true` for Internet Explorer versions less than 9.\r\nexport var ielt9 = ie && !document.addEventListener;\r\n\r\n// @property edge: Boolean; `true` for the Edge web browser.\r\nexport var edge = 'msLaunchUri' in navigator && !('documentMode' in document);\r\n\r\n// @property webkit: Boolean;\r\n// `true` for webkit-based browsers like Chrome and Safari (including mobile versions).\r\nexport var webkit = userAgentContains('webkit');\r\n\r\n// @property android: Boolean\r\n// `true` for any browser running on an Android platform.\r\nexport var android = userAgentContains('android');\r\n\r\n// @property android23: Boolean; `true` for browsers running on Android 2 or Android 3.\r\nexport var android23 = userAgentContains('android 2') || userAgentContains('android 3');\r\n\r\n/* See https://stackoverflow.com/a/17961266 for details on detecting stock Android */\r\nvar webkitVer = parseInt(/WebKit\\/([0-9]+)|$/.exec(navigator.userAgent)[1], 10); // also matches AppleWebKit\r\n// @property androidStock: Boolean; `true` for the Android stock browser (i.e. not Chrome)\r\nexport var androidStock = android && userAgentContains('Google') && webkitVer < 537 && !('AudioNode' in window);\r\n\r\n// @property opera: Boolean; `true` for the Opera browser\r\nexport var opera = !!window.opera;\r\n\r\n// @property chrome: Boolean; `true` for the Chrome browser.\r\nexport var chrome = userAgentContains('chrome');\r\n\r\n// @property gecko: Boolean; `true` for gecko-based browsers like Firefox.\r\nexport var gecko = userAgentContains('gecko') && !webkit && !opera && !ie;\r\n\r\n// @property safari: Boolean; `true` for the Safari browser.\r\nexport var safari = !chrome && userAgentContains('safari');\r\n\r\nexport var phantom = userAgentContains('phantom');\r\n\r\n// @property opera12: Boolean\r\n// `true` for the Opera browser supporting CSS transforms (version 12 or later).\r\nexport var opera12 = 'OTransition' in style;\r\n\r\n// @property win: Boolean; `true` when the browser is running in a Windows platform\r\nexport var win = navigator.platform.indexOf('Win') === 0;\r\n\r\n// @property ie3d: Boolean; `true` for all Internet Explorer versions supporting CSS transforms.\r\nexport var ie3d = ie && ('transition' in style);\r\n\r\n// @property webkit3d: Boolean; `true` for webkit-based browsers supporting CSS transforms.\r\nexport var webkit3d = ('WebKitCSSMatrix' in window) && ('m11' in new window.WebKitCSSMatrix()) && !android23;\r\n\r\n// @property gecko3d: Boolean; `true` for gecko-based browsers supporting CSS transforms.\r\nexport var gecko3d = 'MozPerspective' in style;\r\n\r\n// @property any3d: Boolean\r\n// `true` for all browsers supporting CSS transforms.\r\nexport var any3d = !window.L_DISABLE_3D && (ie3d || webkit3d || gecko3d) && !opera12 && !phantom;\r\n\r\n// @property mobile: Boolean; `true` for all browsers running in a mobile device.\r\nexport var mobile = typeof orientation !== 'undefined' || userAgentContains('mobile');\r\n\r\n// @property mobileWebkit: Boolean; `true` for all webkit-based browsers in a mobile device.\r\nexport var mobileWebkit = mobile && webkit;\r\n\r\n// @property mobileWebkit3d: Boolean\r\n// `true` for all webkit-based browsers in a mobile device supporting CSS transforms.\r\nexport var mobileWebkit3d = mobile && webkit3d;\r\n\r\n// @property msPointer: Boolean\r\n// `true` for browsers implementing the Microsoft touch events model (notably IE10).\r\nexport var msPointer = !window.PointerEvent && window.MSPointerEvent;\r\n\r\n// @property pointer: Boolean\r\n// `true` for all browsers supporting [pointer events](https://msdn.microsoft.com/en-us/library/dn433244%28v=vs.85%29.aspx).\r\nexport var pointer = !webkit && !!(window.PointerEvent || msPointer);\r\n\r\n// @property touch: Boolean\r\n// `true` for all browsers supporting [touch events](https://developer.mozilla.org/docs/Web/API/Touch_events).\r\n// This does not necessarily mean that the browser is running in a computer with\r\n// a touchscreen, it only means that the browser is capable of understanding\r\n// touch events.\r\nexport var touch = !window.L_NO_TOUCH && (pointer || 'ontouchstart' in window ||\r\n\t\t(window.DocumentTouch && document instanceof window.DocumentTouch));\r\n\r\n// @property mobileOpera: Boolean; `true` for the Opera browser in a mobile device.\r\nexport var mobileOpera = mobile && opera;\r\n\r\n// @property mobileGecko: Boolean\r\n// `true` for gecko-based browsers running in a mobile device.\r\nexport var mobileGecko = mobile && gecko;\r\n\r\n// @property retina: Boolean\r\n// `true` for browsers on a high-resolution \"retina\" screen or on any screen when browser's display zoom is more than 100%.\r\nexport var retina = (window.devicePixelRatio || (window.screen.deviceXDPI / window.screen.logicalXDPI)) > 1;\r\n\r\n// @property passiveEvents: Boolean\r\n// `true` for browsers that support passive events.\r\nexport var passiveEvents = (function () {\r\n\tvar supportsPassiveOption = false;\r\n\ttry {\r\n\t\tvar opts = Object.defineProperty({}, 'passive', {\r\n\t\t\tget: function () {\r\n\t\t\t\tsupportsPassiveOption = true;\r\n\t\t\t}\r\n\t\t});\r\n\t\twindow.addEventListener('testPassiveEventSupport', Util.falseFn, opts);\r\n\t\twindow.removeEventListener('testPassiveEventSupport', Util.falseFn, opts);\r\n\t} catch (e) {\r\n\t\t// Errors can safely be ignored since this is only a browser support test.\r\n\t}\r\n\treturn supportsPassiveOption;\r\n});\r\n\r\n// @property canvas: Boolean\r\n// `true` when the browser supports [`